Xmipp  v3.23.11-Nereus
alglibmisc.cpp
Go to the documentation of this file.
1 /*************************************************************************
2 Copyright (c) Sergey Bochkanov (ALGLIB project).
3 
4 >>> SOURCE LICENSE >>>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation (www.fsf.org); either version 2 of the
8 License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 A copy of the GNU General Public License is available at
16 http://www.fsf.org/licensing/licenses
17 >>> END OF LICENSE >>>
18 *************************************************************************/
19 #include "stdafx.h"
20 #include "alglibmisc.h"
21 
22 // disable some irrelevant warnings
23 #if (AE_COMPILER==AE_MSVC)
24 #pragma warning(disable:4100)
25 #pragma warning(disable:4127)
26 #pragma warning(disable:4702)
27 #pragma warning(disable:4996)
28 #endif
29 using namespace std;
30 
32 //
33 // THIS SECTION CONTAINS IMPLEMENTATION OF C++ INTERFACE
34 //
36 namespace alglib
37 {
38 
39 
40 /*************************************************************************
41 Portable high quality random number generator state.
42 Initialized with HQRNDRandomize() or HQRNDSeed().
43 
44 Fields:
45  S1, S2 - seed values
46  V - precomputed value
47  MagicV - 'magic' value used to determine whether State structure
48  was correctly initialized.
49 *************************************************************************/
50 _hqrndstate_owner::_hqrndstate_owner()
51 {
53  if( p_struct==NULL )
54  throw ap_error("ALGLIB: malloc error");
55  if( !alglib_impl::_hqrndstate_init(p_struct, NULL, ae_false) )
56  throw ap_error("ALGLIB: malloc error");
57 }
58 
59 _hqrndstate_owner::_hqrndstate_owner(const _hqrndstate_owner &rhs)
60 {
62  if( p_struct==NULL )
63  throw ap_error("ALGLIB: malloc error");
64  if( !alglib_impl::_hqrndstate_init_copy(p_struct, const_cast<alglib_impl::hqrndstate*>(rhs.p_struct), NULL, ae_false) )
65  throw ap_error("ALGLIB: malloc error");
66 }
67 
68 _hqrndstate_owner& _hqrndstate_owner::operator=(const _hqrndstate_owner &rhs)
69 {
70  if( this==&rhs )
71  return *this;
73  if( !alglib_impl::_hqrndstate_init_copy(p_struct, const_cast<alglib_impl::hqrndstate*>(rhs.p_struct), NULL, ae_false) )
74  throw ap_error("ALGLIB: malloc error");
75  return *this;
76 }
77 
78 _hqrndstate_owner::~_hqrndstate_owner()
79 {
81  ae_free(p_struct);
82 }
83 
84 alglib_impl::hqrndstate* _hqrndstate_owner::c_ptr()
85 {
86  return p_struct;
87 }
88 
89 alglib_impl::hqrndstate* _hqrndstate_owner::c_ptr() const
90 {
91  return const_cast<alglib_impl::hqrndstate*>(p_struct);
92 }
93 hqrndstate::hqrndstate() : _hqrndstate_owner()
94 {
95 }
96 
98 {
99 }
100 
102 {
103  if( this==&rhs )
104  return *this;
106  return *this;
107 }
108 
110 {
111 }
112 
113 /*************************************************************************
114 HQRNDState initialization with random values which come from standard
115 RNG.
116 
117  -- ALGLIB --
118  Copyright 02.12.2009 by Bochkanov Sergey
119 *************************************************************************/
121 {
122  alglib_impl::ae_state _alglib_env_state;
123  alglib_impl::ae_state_init(&_alglib_env_state);
124  try
125  {
126  alglib_impl::hqrndrandomize(const_cast<alglib_impl::hqrndstate*>(state.c_ptr()), &_alglib_env_state);
127  alglib_impl::ae_state_clear(&_alglib_env_state);
128  return;
129  }
131  {
132  throw ap_error(_alglib_env_state.error_msg);
133  }
134 }
135 
136 /*************************************************************************
137 HQRNDState initialization with seed values
138 
139  -- ALGLIB --
140  Copyright 02.12.2009 by Bochkanov Sergey
141 *************************************************************************/
142 void hqrndseed(const ae_int_t s1, const ae_int_t s2, hqrndstate &state)
143 {
144  alglib_impl::ae_state _alglib_env_state;
145  alglib_impl::ae_state_init(&_alglib_env_state);
146  try
147  {
148  alglib_impl::hqrndseed(s1, s2, const_cast<alglib_impl::hqrndstate*>(state.c_ptr()), &_alglib_env_state);
149  alglib_impl::ae_state_clear(&_alglib_env_state);
150  return;
151  }
153  {
154  throw ap_error(_alglib_env_state.error_msg);
155  }
156 }
157 
158 /*************************************************************************
159 This function generates random real number in (0,1),
160 not including interval boundaries
161 
162 State structure must be initialized with HQRNDRandomize() or HQRNDSeed().
163 
164  -- ALGLIB --
165  Copyright 02.12.2009 by Bochkanov Sergey
166 *************************************************************************/
167 double hqrnduniformr(const hqrndstate &state)
168 {
169  alglib_impl::ae_state _alglib_env_state;
170  alglib_impl::ae_state_init(&_alglib_env_state);
171  try
172  {
173  double result = alglib_impl::hqrnduniformr(const_cast<alglib_impl::hqrndstate*>(state.c_ptr()), &_alglib_env_state);
174  alglib_impl::ae_state_clear(&_alglib_env_state);
175  return *(reinterpret_cast<double*>(&result));
176  }
178  {
179  throw ap_error(_alglib_env_state.error_msg);
180  }
181 }
182 
183 /*************************************************************************
184 This function generates random integer number in [0, N)
185 
186 1. State structure must be initialized with HQRNDRandomize() or HQRNDSeed()
187 2. N can be any positive number except for very large numbers:
188  * close to 2^31 on 32-bit systems
189  * close to 2^62 on 64-bit systems
190  An exception will be generated if N is too large.
191 
192  -- ALGLIB --
193  Copyright 02.12.2009 by Bochkanov Sergey
194 *************************************************************************/
196 {
197  alglib_impl::ae_state _alglib_env_state;
198  alglib_impl::ae_state_init(&_alglib_env_state);
199  try
200  {
201  alglib_impl::ae_int_t result = alglib_impl::hqrnduniformi(const_cast<alglib_impl::hqrndstate*>(state.c_ptr()), n, &_alglib_env_state);
202  alglib_impl::ae_state_clear(&_alglib_env_state);
203  return *(reinterpret_cast<ae_int_t*>(&result));
204  }
206  {
207  throw ap_error(_alglib_env_state.error_msg);
208  }
209 }
210 
211 /*************************************************************************
212 Random number generator: normal numbers
213 
214 This function generates one random number from normal distribution.
215 Its performance is equal to that of HQRNDNormal2()
216 
217 State structure must be initialized with HQRNDRandomize() or HQRNDSeed().
218 
219  -- ALGLIB --
220  Copyright 02.12.2009 by Bochkanov Sergey
221 *************************************************************************/
222 double hqrndnormal(const hqrndstate &state)
223 {
224  alglib_impl::ae_state _alglib_env_state;
225  alglib_impl::ae_state_init(&_alglib_env_state);
226  try
227  {
228  double result = alglib_impl::hqrndnormal(const_cast<alglib_impl::hqrndstate*>(state.c_ptr()), &_alglib_env_state);
229  alglib_impl::ae_state_clear(&_alglib_env_state);
230  return *(reinterpret_cast<double*>(&result));
231  }
233  {
234  throw ap_error(_alglib_env_state.error_msg);
235  }
236 }
237 
238 /*************************************************************************
239 Random number generator: random X and Y such that X^2+Y^2=1
240 
241 State structure must be initialized with HQRNDRandomize() or HQRNDSeed().
242 
243  -- ALGLIB --
244  Copyright 02.12.2009 by Bochkanov Sergey
245 *************************************************************************/
246 void hqrndunit2(const hqrndstate &state, double &x, double &y)
247 {
248  alglib_impl::ae_state _alglib_env_state;
249  alglib_impl::ae_state_init(&_alglib_env_state);
250  try
251  {
252  alglib_impl::hqrndunit2(const_cast<alglib_impl::hqrndstate*>(state.c_ptr()), &x, &y, &_alglib_env_state);
253  alglib_impl::ae_state_clear(&_alglib_env_state);
254  return;
255  }
257  {
258  throw ap_error(_alglib_env_state.error_msg);
259  }
260 }
261 
262 /*************************************************************************
263 Random number generator: normal numbers
264 
265 This function generates two independent random numbers from normal
266 distribution. Its performance is equal to that of HQRNDNormal()
267 
268 State structure must be initialized with HQRNDRandomize() or HQRNDSeed().
269 
270  -- ALGLIB --
271  Copyright 02.12.2009 by Bochkanov Sergey
272 *************************************************************************/
273 void hqrndnormal2(const hqrndstate &state, double &x1, double &x2)
274 {
275  alglib_impl::ae_state _alglib_env_state;
276  alglib_impl::ae_state_init(&_alglib_env_state);
277  try
278  {
279  alglib_impl::hqrndnormal2(const_cast<alglib_impl::hqrndstate*>(state.c_ptr()), &x1, &x2, &_alglib_env_state);
280  alglib_impl::ae_state_clear(&_alglib_env_state);
281  return;
282  }
284  {
285  throw ap_error(_alglib_env_state.error_msg);
286  }
287 }
288 
289 /*************************************************************************
290 Random number generator: exponential distribution
291 
292 State structure must be initialized with HQRNDRandomize() or HQRNDSeed().
293 
294  -- ALGLIB --
295  Copyright 11.08.2007 by Bochkanov Sergey
296 *************************************************************************/
297 double hqrndexponential(const hqrndstate &state, const double lambdav)
298 {
299  alglib_impl::ae_state _alglib_env_state;
300  alglib_impl::ae_state_init(&_alglib_env_state);
301  try
302  {
303  double result = alglib_impl::hqrndexponential(const_cast<alglib_impl::hqrndstate*>(state.c_ptr()), lambdav, &_alglib_env_state);
304  alglib_impl::ae_state_clear(&_alglib_env_state);
305  return *(reinterpret_cast<double*>(&result));
306  }
308  {
309  throw ap_error(_alglib_env_state.error_msg);
310  }
311 }
312 
313 /*************************************************************************
314 This function generates random number from discrete distribution given by
315 finite sample X.
316 
317 INPUT PARAMETERS
318  State - high quality random number generator, must be
319  initialized with HQRNDRandomize() or HQRNDSeed().
320  X - finite sample
321  N - number of elements to use, N>=1
322 
323 RESULT
324  this function returns one of the X[i] for random i=0..N-1
325 
326  -- ALGLIB --
327  Copyright 08.11.2011 by Bochkanov Sergey
328 *************************************************************************/
329 double hqrnddiscrete(const hqrndstate &state, const real_1d_array &x, const ae_int_t n)
330 {
331  alglib_impl::ae_state _alglib_env_state;
332  alglib_impl::ae_state_init(&_alglib_env_state);
333  try
334  {
335  double result = alglib_impl::hqrnddiscrete(const_cast<alglib_impl::hqrndstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), n, &_alglib_env_state);
336  alglib_impl::ae_state_clear(&_alglib_env_state);
337  return *(reinterpret_cast<double*>(&result));
338  }
340  {
341  throw ap_error(_alglib_env_state.error_msg);
342  }
343 }
344 
345 /*************************************************************************
346 This function generates random number from continuous distribution given
347 by finite sample X.
348 
349 INPUT PARAMETERS
350  State - high quality random number generator, must be
351  initialized with HQRNDRandomize() or HQRNDSeed().
352  X - finite sample, array[N] (can be larger, in this case only
353  leading N elements are used). THIS ARRAY MUST BE SORTED BY
354  ASCENDING.
355  N - number of elements to use, N>=1
356 
357 RESULT
358  this function returns random number from continuous distribution which
359  tries to approximate X as mush as possible. min(X)<=Result<=max(X).
360 
361  -- ALGLIB --
362  Copyright 08.11.2011 by Bochkanov Sergey
363 *************************************************************************/
364 double hqrndcontinuous(const hqrndstate &state, const real_1d_array &x, const ae_int_t n)
365 {
366  alglib_impl::ae_state _alglib_env_state;
367  alglib_impl::ae_state_init(&_alglib_env_state);
368  try
369  {
370  double result = alglib_impl::hqrndcontinuous(const_cast<alglib_impl::hqrndstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), n, &_alglib_env_state);
371  alglib_impl::ae_state_clear(&_alglib_env_state);
372  return *(reinterpret_cast<double*>(&result));
373  }
375  {
376  throw ap_error(_alglib_env_state.error_msg);
377  }
378 }
379 
380 /*************************************************************************
381 
382 *************************************************************************/
384 {
386  if( p_struct==NULL )
387  throw ap_error("ALGLIB: malloc error");
389  throw ap_error("ALGLIB: malloc error");
390 }
391 
393 {
395  if( p_struct==NULL )
396  throw ap_error("ALGLIB: malloc error");
397  if( !alglib_impl::_kdtree_init_copy(p_struct, const_cast<alglib_impl::kdtree*>(rhs.p_struct), NULL, ae_false) )
398  throw ap_error("ALGLIB: malloc error");
399 }
400 
402 {
403  if( this==&rhs )
404  return *this;
406  if( !alglib_impl::_kdtree_init_copy(p_struct, const_cast<alglib_impl::kdtree*>(rhs.p_struct), NULL, ae_false) )
407  throw ap_error("ALGLIB: malloc error");
408  return *this;
409 }
410 
412 {
414  ae_free(p_struct);
415 }
416 
418 {
419  return p_struct;
420 }
421 
423 {
424  return const_cast<alglib_impl::kdtree*>(p_struct);
425 }
427 {
428 }
429 
431 {
432 }
433 
435 {
436  if( this==&rhs )
437  return *this;
439  return *this;
440 }
441 
443 {
444 }
445 
446 
447 /*************************************************************************
448 This function serializes data structure to string.
449 
450 Important properties of s_out:
451 * it contains alphanumeric characters, dots, underscores, minus signs
452 * these symbols are grouped into words, which are separated by spaces
453  and Windows-style (CR+LF) newlines
454 * although serializer uses spaces and CR+LF as separators, you can
455  replace any separator character by arbitrary combination of spaces,
456  tabs, Windows or Unix newlines. It allows flexible reformatting of
457  the string in case you want to include it into text or XML file.
458  But you should not insert separators into the middle of the "words"
459  nor you should change case of letters.
460 * s_out can be freely moved between 32-bit and 64-bit systems, little
461  and big endian machines, and so on. You can serialize structure on
462  32-bit machine and unserialize it on 64-bit one (or vice versa), or
463  serialize it on SPARC and unserialize on x86. You can also
464  serialize it in C++ version of ALGLIB and unserialize in C# one,
465  and vice versa.
466 *************************************************************************/
467 void kdtreeserialize(kdtree &obj, std::string &s_out)
468 {
469  alglib_impl::ae_state state;
470  alglib_impl::ae_serializer serializer;
471  alglib_impl::ae_int_t ssize;
472 
474  try
475  {
476  alglib_impl::ae_serializer_init(&serializer);
478  alglib_impl::kdtreealloc(&serializer, obj.c_ptr(), &state);
479  ssize = alglib_impl::ae_serializer_get_alloc_size(&serializer);
480  s_out.clear();
481  s_out.reserve((size_t)(ssize+1));
482  alglib_impl::ae_serializer_sstart_str(&serializer, &s_out);
483  alglib_impl::kdtreeserialize(&serializer, obj.c_ptr(), &state);
484  alglib_impl::ae_serializer_stop(&serializer);
485  if( s_out.length()>(size_t)ssize )
486  throw ap_error("ALGLIB: serialization integrity error");
489  }
491  {
492  throw ap_error(state.error_msg);
493  }
494 }
495 /*************************************************************************
496 This function unserializes data structure from string.
497 *************************************************************************/
498 void kdtreeunserialize(std::string &s_in, kdtree &obj)
499 {
500  alglib_impl::ae_state state;
501  alglib_impl::ae_serializer serializer;
502 
504  try
505  {
506  alglib_impl::ae_serializer_init(&serializer);
507  alglib_impl::ae_serializer_ustart_str(&serializer, &s_in);
508  alglib_impl::kdtreeunserialize(&serializer, obj.c_ptr(), &state);
509  alglib_impl::ae_serializer_stop(&serializer);
512  }
514  {
515  throw ap_error(state.error_msg);
516  }
517 }
518 
519 /*************************************************************************
520 KD-tree creation
521 
522 This subroutine creates KD-tree from set of X-values and optional Y-values
523 
524 INPUT PARAMETERS
525  XY - dataset, array[0..N-1,0..NX+NY-1].
526  one row corresponds to one point.
527  first NX columns contain X-values, next NY (NY may be zero)
528  columns may contain associated Y-values
529  N - number of points, N>=0.
530  NX - space dimension, NX>=1.
531  NY - number of optional Y-values, NY>=0.
532  NormType- norm type:
533  * 0 denotes infinity-norm
534  * 1 denotes 1-norm
535  * 2 denotes 2-norm (Euclidean norm)
536 
537 OUTPUT PARAMETERS
538  KDT - KD-tree
539 
540 
541 NOTES
542 
543 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory
544  requirements.
545 2. Although KD-trees may be used with any combination of N and NX, they
546  are more efficient than brute-force search only when N >> 4^NX. So they
547  are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another
548  inefficient case, because simple binary search (without additional
549  structures) is much more efficient in such tasks than KD-trees.
550 
551  -- ALGLIB --
552  Copyright 28.02.2010 by Bochkanov Sergey
553 *************************************************************************/
554 void kdtreebuild(const real_2d_array &xy, const ae_int_t n, const ae_int_t nx, const ae_int_t ny, const ae_int_t normtype, kdtree &kdt)
555 {
556  alglib_impl::ae_state _alglib_env_state;
557  alglib_impl::ae_state_init(&_alglib_env_state);
558  try
559  {
560  alglib_impl::kdtreebuild(const_cast<alglib_impl::ae_matrix*>(xy.c_ptr()), n, nx, ny, normtype, const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), &_alglib_env_state);
561  alglib_impl::ae_state_clear(&_alglib_env_state);
562  return;
563  }
565  {
566  throw ap_error(_alglib_env_state.error_msg);
567  }
568 }
569 
570 /*************************************************************************
571 KD-tree creation
572 
573 This subroutine creates KD-tree from set of X-values and optional Y-values
574 
575 INPUT PARAMETERS
576  XY - dataset, array[0..N-1,0..NX+NY-1].
577  one row corresponds to one point.
578  first NX columns contain X-values, next NY (NY may be zero)
579  columns may contain associated Y-values
580  N - number of points, N>=0.
581  NX - space dimension, NX>=1.
582  NY - number of optional Y-values, NY>=0.
583  NormType- norm type:
584  * 0 denotes infinity-norm
585  * 1 denotes 1-norm
586  * 2 denotes 2-norm (Euclidean norm)
587 
588 OUTPUT PARAMETERS
589  KDT - KD-tree
590 
591 
592 NOTES
593 
594 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory
595  requirements.
596 2. Although KD-trees may be used with any combination of N and NX, they
597  are more efficient than brute-force search only when N >> 4^NX. So they
598  are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another
599  inefficient case, because simple binary search (without additional
600  structures) is much more efficient in such tasks than KD-trees.
601 
602  -- ALGLIB --
603  Copyright 28.02.2010 by Bochkanov Sergey
604 *************************************************************************/
605 void kdtreebuild(const real_2d_array &xy, const ae_int_t nx, const ae_int_t ny, const ae_int_t normtype, kdtree &kdt)
606 {
607  alglib_impl::ae_state _alglib_env_state;
608  ae_int_t n;
609 
610  n = xy.rows();
611  alglib_impl::ae_state_init(&_alglib_env_state);
612  try
613  {
614  alglib_impl::kdtreebuild(const_cast<alglib_impl::ae_matrix*>(xy.c_ptr()), n, nx, ny, normtype, const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), &_alglib_env_state);
615 
616  alglib_impl::ae_state_clear(&_alglib_env_state);
617  return;
618  }
620  {
621  throw ap_error(_alglib_env_state.error_msg);
622  }
623 }
624 
625 /*************************************************************************
626 KD-tree creation
627 
628 This subroutine creates KD-tree from set of X-values, integer tags and
629 optional Y-values
630 
631 INPUT PARAMETERS
632  XY - dataset, array[0..N-1,0..NX+NY-1].
633  one row corresponds to one point.
634  first NX columns contain X-values, next NY (NY may be zero)
635  columns may contain associated Y-values
636  Tags - tags, array[0..N-1], contains integer tags associated
637  with points.
638  N - number of points, N>=0
639  NX - space dimension, NX>=1.
640  NY - number of optional Y-values, NY>=0.
641  NormType- norm type:
642  * 0 denotes infinity-norm
643  * 1 denotes 1-norm
644  * 2 denotes 2-norm (Euclidean norm)
645 
646 OUTPUT PARAMETERS
647  KDT - KD-tree
648 
649 NOTES
650 
651 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory
652  requirements.
653 2. Although KD-trees may be used with any combination of N and NX, they
654  are more efficient than brute-force search only when N >> 4^NX. So they
655  are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another
656  inefficient case, because simple binary search (without additional
657  structures) is much more efficient in such tasks than KD-trees.
658 
659  -- ALGLIB --
660  Copyright 28.02.2010 by Bochkanov Sergey
661 *************************************************************************/
662 void kdtreebuildtagged(const real_2d_array &xy, const integer_1d_array &tags, const ae_int_t n, const ae_int_t nx, const ae_int_t ny, const ae_int_t normtype, kdtree &kdt)
663 {
664  alglib_impl::ae_state _alglib_env_state;
665  alglib_impl::ae_state_init(&_alglib_env_state);
666  try
667  {
668  alglib_impl::kdtreebuildtagged(const_cast<alglib_impl::ae_matrix*>(xy.c_ptr()), const_cast<alglib_impl::ae_vector*>(tags.c_ptr()), n, nx, ny, normtype, const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), &_alglib_env_state);
669  alglib_impl::ae_state_clear(&_alglib_env_state);
670  return;
671  }
673  {
674  throw ap_error(_alglib_env_state.error_msg);
675  }
676 }
677 
678 /*************************************************************************
679 KD-tree creation
680 
681 This subroutine creates KD-tree from set of X-values, integer tags and
682 optional Y-values
683 
684 INPUT PARAMETERS
685  XY - dataset, array[0..N-1,0..NX+NY-1].
686  one row corresponds to one point.
687  first NX columns contain X-values, next NY (NY may be zero)
688  columns may contain associated Y-values
689  Tags - tags, array[0..N-1], contains integer tags associated
690  with points.
691  N - number of points, N>=0
692  NX - space dimension, NX>=1.
693  NY - number of optional Y-values, NY>=0.
694  NormType- norm type:
695  * 0 denotes infinity-norm
696  * 1 denotes 1-norm
697  * 2 denotes 2-norm (Euclidean norm)
698 
699 OUTPUT PARAMETERS
700  KDT - KD-tree
701 
702 NOTES
703 
704 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory
705  requirements.
706 2. Although KD-trees may be used with any combination of N and NX, they
707  are more efficient than brute-force search only when N >> 4^NX. So they
708  are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another
709  inefficient case, because simple binary search (without additional
710  structures) is much more efficient in such tasks than KD-trees.
711 
712  -- ALGLIB --
713  Copyright 28.02.2010 by Bochkanov Sergey
714 *************************************************************************/
715 void kdtreebuildtagged(const real_2d_array &xy, const integer_1d_array &tags, const ae_int_t nx, const ae_int_t ny, const ae_int_t normtype, kdtree &kdt)
716 {
717  alglib_impl::ae_state _alglib_env_state;
718  ae_int_t n;
719  if( (xy.rows()!=tags.length()))
720  throw ap_error("Error while calling 'kdtreebuildtagged': looks like one of arguments has wrong size");
721  n = xy.rows();
722  alglib_impl::ae_state_init(&_alglib_env_state);
723  try
724  {
725  alglib_impl::kdtreebuildtagged(const_cast<alglib_impl::ae_matrix*>(xy.c_ptr()), const_cast<alglib_impl::ae_vector*>(tags.c_ptr()), n, nx, ny, normtype, const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), &_alglib_env_state);
726 
727  alglib_impl::ae_state_clear(&_alglib_env_state);
728  return;
729  }
731  {
732  throw ap_error(_alglib_env_state.error_msg);
733  }
734 }
735 
736 /*************************************************************************
737 K-NN query: K nearest neighbors
738 
739 INPUT PARAMETERS
740  KDT - KD-tree
741  X - point, array[0..NX-1].
742  K - number of neighbors to return, K>=1
743  SelfMatch - whether self-matches are allowed:
744  * if True, nearest neighbor may be the point itself
745  (if it exists in original dataset)
746  * if False, then only points with non-zero distance
747  are returned
748  * if not given, considered True
749 
750 RESULT
751  number of actual neighbors found (either K or N, if K>N).
752 
753 This subroutine performs query and stores its result in the internal
754 structures of the KD-tree. You can use following subroutines to obtain
755 these results:
756 * KDTreeQueryResultsX() to get X-values
757 * KDTreeQueryResultsXY() to get X- and Y-values
758 * KDTreeQueryResultsTags() to get tag values
759 * KDTreeQueryResultsDistances() to get distances
760 
761  -- ALGLIB --
762  Copyright 28.02.2010 by Bochkanov Sergey
763 *************************************************************************/
764 ae_int_t kdtreequeryknn(const kdtree &kdt, const real_1d_array &x, const ae_int_t k, const bool selfmatch)
765 {
766  alglib_impl::ae_state _alglib_env_state;
767  alglib_impl::ae_state_init(&_alglib_env_state);
768  try
769  {
770  alglib_impl::ae_int_t result = alglib_impl::kdtreequeryknn(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), k, selfmatch, &_alglib_env_state);
771  alglib_impl::ae_state_clear(&_alglib_env_state);
772  return *(reinterpret_cast<ae_int_t*>(&result));
773  }
775  {
776  throw ap_error(_alglib_env_state.error_msg);
777  }
778 }
779 
780 /*************************************************************************
781 K-NN query: K nearest neighbors
782 
783 INPUT PARAMETERS
784  KDT - KD-tree
785  X - point, array[0..NX-1].
786  K - number of neighbors to return, K>=1
787  SelfMatch - whether self-matches are allowed:
788  * if True, nearest neighbor may be the point itself
789  (if it exists in original dataset)
790  * if False, then only points with non-zero distance
791  are returned
792  * if not given, considered True
793 
794 RESULT
795  number of actual neighbors found (either K or N, if K>N).
796 
797 This subroutine performs query and stores its result in the internal
798 structures of the KD-tree. You can use following subroutines to obtain
799 these results:
800 * KDTreeQueryResultsX() to get X-values
801 * KDTreeQueryResultsXY() to get X- and Y-values
802 * KDTreeQueryResultsTags() to get tag values
803 * KDTreeQueryResultsDistances() to get distances
804 
805  -- ALGLIB --
806  Copyright 28.02.2010 by Bochkanov Sergey
807 *************************************************************************/
809 {
810  alglib_impl::ae_state _alglib_env_state;
811  bool selfmatch;
812 
813  selfmatch = true;
814  alglib_impl::ae_state_init(&_alglib_env_state);
815  try
816  {
817  alglib_impl::ae_int_t result = alglib_impl::kdtreequeryknn(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), k, selfmatch, &_alglib_env_state);
818 
819  alglib_impl::ae_state_clear(&_alglib_env_state);
820  return *(reinterpret_cast<ae_int_t*>(&result));
821  }
823  {
824  throw ap_error(_alglib_env_state.error_msg);
825  }
826 }
827 
828 /*************************************************************************
829 R-NN query: all points within R-sphere centered at X
830 
831 INPUT PARAMETERS
832  KDT - KD-tree
833  X - point, array[0..NX-1].
834  R - radius of sphere (in corresponding norm), R>0
835  SelfMatch - whether self-matches are allowed:
836  * if True, nearest neighbor may be the point itself
837  (if it exists in original dataset)
838  * if False, then only points with non-zero distance
839  are returned
840  * if not given, considered True
841 
842 RESULT
843  number of neighbors found, >=0
844 
845 This subroutine performs query and stores its result in the internal
846 structures of the KD-tree. You can use following subroutines to obtain
847 actual results:
848 * KDTreeQueryResultsX() to get X-values
849 * KDTreeQueryResultsXY() to get X- and Y-values
850 * KDTreeQueryResultsTags() to get tag values
851 * KDTreeQueryResultsDistances() to get distances
852 
853  -- ALGLIB --
854  Copyright 28.02.2010 by Bochkanov Sergey
855 *************************************************************************/
856 ae_int_t kdtreequeryrnn(const kdtree &kdt, const real_1d_array &x, const double r, const bool selfmatch)
857 {
858  alglib_impl::ae_state _alglib_env_state;
859  alglib_impl::ae_state_init(&_alglib_env_state);
860  try
861  {
862  alglib_impl::ae_int_t result = alglib_impl::kdtreequeryrnn(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), r, selfmatch, &_alglib_env_state);
863  alglib_impl::ae_state_clear(&_alglib_env_state);
864  return *(reinterpret_cast<ae_int_t*>(&result));
865  }
867  {
868  throw ap_error(_alglib_env_state.error_msg);
869  }
870 }
871 
872 /*************************************************************************
873 R-NN query: all points within R-sphere centered at X
874 
875 INPUT PARAMETERS
876  KDT - KD-tree
877  X - point, array[0..NX-1].
878  R - radius of sphere (in corresponding norm), R>0
879  SelfMatch - whether self-matches are allowed:
880  * if True, nearest neighbor may be the point itself
881  (if it exists in original dataset)
882  * if False, then only points with non-zero distance
883  are returned
884  * if not given, considered True
885 
886 RESULT
887  number of neighbors found, >=0
888 
889 This subroutine performs query and stores its result in the internal
890 structures of the KD-tree. You can use following subroutines to obtain
891 actual results:
892 * KDTreeQueryResultsX() to get X-values
893 * KDTreeQueryResultsXY() to get X- and Y-values
894 * KDTreeQueryResultsTags() to get tag values
895 * KDTreeQueryResultsDistances() to get distances
896 
897  -- ALGLIB --
898  Copyright 28.02.2010 by Bochkanov Sergey
899 *************************************************************************/
900 ae_int_t kdtreequeryrnn(const kdtree &kdt, const real_1d_array &x, const double r)
901 {
902  alglib_impl::ae_state _alglib_env_state;
903  bool selfmatch;
904 
905  selfmatch = true;
906  alglib_impl::ae_state_init(&_alglib_env_state);
907  try
908  {
909  alglib_impl::ae_int_t result = alglib_impl::kdtreequeryrnn(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), r, selfmatch, &_alglib_env_state);
910 
911  alglib_impl::ae_state_clear(&_alglib_env_state);
912  return *(reinterpret_cast<ae_int_t*>(&result));
913  }
915  {
916  throw ap_error(_alglib_env_state.error_msg);
917  }
918 }
919 
920 /*************************************************************************
921 K-NN query: approximate K nearest neighbors
922 
923 INPUT PARAMETERS
924  KDT - KD-tree
925  X - point, array[0..NX-1].
926  K - number of neighbors to return, K>=1
927  SelfMatch - whether self-matches are allowed:
928  * if True, nearest neighbor may be the point itself
929  (if it exists in original dataset)
930  * if False, then only points with non-zero distance
931  are returned
932  * if not given, considered True
933  Eps - approximation factor, Eps>=0. eps-approximate nearest
934  neighbor is a neighbor whose distance from X is at
935  most (1+eps) times distance of true nearest neighbor.
936 
937 RESULT
938  number of actual neighbors found (either K or N, if K>N).
939 
940 NOTES
941  significant performance gain may be achieved only when Eps is is on
942  the order of magnitude of 1 or larger.
943 
944 This subroutine performs query and stores its result in the internal
945 structures of the KD-tree. You can use following subroutines to obtain
946 these results:
947 * KDTreeQueryResultsX() to get X-values
948 * KDTreeQueryResultsXY() to get X- and Y-values
949 * KDTreeQueryResultsTags() to get tag values
950 * KDTreeQueryResultsDistances() to get distances
951 
952  -- ALGLIB --
953  Copyright 28.02.2010 by Bochkanov Sergey
954 *************************************************************************/
955 ae_int_t kdtreequeryaknn(const kdtree &kdt, const real_1d_array &x, const ae_int_t k, const bool selfmatch, const double eps)
956 {
957  alglib_impl::ae_state _alglib_env_state;
958  alglib_impl::ae_state_init(&_alglib_env_state);
959  try
960  {
961  alglib_impl::ae_int_t result = alglib_impl::kdtreequeryaknn(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), k, selfmatch, eps, &_alglib_env_state);
962  alglib_impl::ae_state_clear(&_alglib_env_state);
963  return *(reinterpret_cast<ae_int_t*>(&result));
964  }
966  {
967  throw ap_error(_alglib_env_state.error_msg);
968  }
969 }
970 
971 /*************************************************************************
972 K-NN query: approximate K nearest neighbors
973 
974 INPUT PARAMETERS
975  KDT - KD-tree
976  X - point, array[0..NX-1].
977  K - number of neighbors to return, K>=1
978  SelfMatch - whether self-matches are allowed:
979  * if True, nearest neighbor may be the point itself
980  (if it exists in original dataset)
981  * if False, then only points with non-zero distance
982  are returned
983  * if not given, considered True
984  Eps - approximation factor, Eps>=0. eps-approximate nearest
985  neighbor is a neighbor whose distance from X is at
986  most (1+eps) times distance of true nearest neighbor.
987 
988 RESULT
989  number of actual neighbors found (either K or N, if K>N).
990 
991 NOTES
992  significant performance gain may be achieved only when Eps is is on
993  the order of magnitude of 1 or larger.
994 
995 This subroutine performs query and stores its result in the internal
996 structures of the KD-tree. You can use following subroutines to obtain
997 these results:
998 * KDTreeQueryResultsX() to get X-values
999 * KDTreeQueryResultsXY() to get X- and Y-values
1000 * KDTreeQueryResultsTags() to get tag values
1001 * KDTreeQueryResultsDistances() to get distances
1002 
1003  -- ALGLIB --
1004  Copyright 28.02.2010 by Bochkanov Sergey
1005 *************************************************************************/
1006 ae_int_t kdtreequeryaknn(const kdtree &kdt, const real_1d_array &x, const ae_int_t k, const double eps)
1007 {
1008  alglib_impl::ae_state _alglib_env_state;
1009  bool selfmatch;
1010 
1011  selfmatch = true;
1012  alglib_impl::ae_state_init(&_alglib_env_state);
1013  try
1014  {
1015  alglib_impl::ae_int_t result = alglib_impl::kdtreequeryaknn(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), k, selfmatch, eps, &_alglib_env_state);
1016 
1017  alglib_impl::ae_state_clear(&_alglib_env_state);
1018  return *(reinterpret_cast<ae_int_t*>(&result));
1019  }
1021  {
1022  throw ap_error(_alglib_env_state.error_msg);
1023  }
1024 }
1025 
1026 /*************************************************************************
1027 X-values from last query
1028 
1029 INPUT PARAMETERS
1030  KDT - KD-tree
1031  X - possibly pre-allocated buffer. If X is too small to store
1032  result, it is resized. If size(X) is enough to store
1033  result, it is left unchanged.
1034 
1035 OUTPUT PARAMETERS
1036  X - rows are filled with X-values
1037 
1038 NOTES
1039 1. points are ordered by distance from the query point (first = closest)
1040 2. if XY is larger than required to store result, only leading part will
1041  be overwritten; trailing part will be left unchanged. So if on input
1042  XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get
1043  XY = [[1,2],[C,D]]. This is done purposely to increase performance; if
1044  you want function to resize array according to result size, use
1045  function with same name and suffix 'I'.
1046 
1047 SEE ALSO
1048 * KDTreeQueryResultsXY() X- and Y-values
1049 * KDTreeQueryResultsTags() tag values
1050 * KDTreeQueryResultsDistances() distances
1051 
1052  -- ALGLIB --
1053  Copyright 28.02.2010 by Bochkanov Sergey
1054 *************************************************************************/
1056 {
1057  alglib_impl::ae_state _alglib_env_state;
1058  alglib_impl::ae_state_init(&_alglib_env_state);
1059  try
1060  {
1061  alglib_impl::kdtreequeryresultsx(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
1062  alglib_impl::ae_state_clear(&_alglib_env_state);
1063  return;
1064  }
1066  {
1067  throw ap_error(_alglib_env_state.error_msg);
1068  }
1069 }
1070 
1071 /*************************************************************************
1072 X- and Y-values from last query
1073 
1074 INPUT PARAMETERS
1075  KDT - KD-tree
1076  XY - possibly pre-allocated buffer. If XY is too small to store
1077  result, it is resized. If size(XY) is enough to store
1078  result, it is left unchanged.
1079 
1080 OUTPUT PARAMETERS
1081  XY - rows are filled with points: first NX columns with
1082  X-values, next NY columns - with Y-values.
1083 
1084 NOTES
1085 1. points are ordered by distance from the query point (first = closest)
1086 2. if XY is larger than required to store result, only leading part will
1087  be overwritten; trailing part will be left unchanged. So if on input
1088  XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get
1089  XY = [[1,2],[C,D]]. This is done purposely to increase performance; if
1090  you want function to resize array according to result size, use
1091  function with same name and suffix 'I'.
1092 
1093 SEE ALSO
1094 * KDTreeQueryResultsX() X-values
1095 * KDTreeQueryResultsTags() tag values
1096 * KDTreeQueryResultsDistances() distances
1097 
1098  -- ALGLIB --
1099  Copyright 28.02.2010 by Bochkanov Sergey
1100 *************************************************************************/
1102 {
1103  alglib_impl::ae_state _alglib_env_state;
1104  alglib_impl::ae_state_init(&_alglib_env_state);
1105  try
1106  {
1107  alglib_impl::kdtreequeryresultsxy(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.c_ptr()), &_alglib_env_state);
1108  alglib_impl::ae_state_clear(&_alglib_env_state);
1109  return;
1110  }
1112  {
1113  throw ap_error(_alglib_env_state.error_msg);
1114  }
1115 }
1116 
1117 /*************************************************************************
1118 Tags from last query
1119 
1120 INPUT PARAMETERS
1121  KDT - KD-tree
1122  Tags - possibly pre-allocated buffer. If X is too small to store
1123  result, it is resized. If size(X) is enough to store
1124  result, it is left unchanged.
1125 
1126 OUTPUT PARAMETERS
1127  Tags - filled with tags associated with points,
1128  or, when no tags were supplied, with zeros
1129 
1130 NOTES
1131 1. points are ordered by distance from the query point (first = closest)
1132 2. if XY is larger than required to store result, only leading part will
1133  be overwritten; trailing part will be left unchanged. So if on input
1134  XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get
1135  XY = [[1,2],[C,D]]. This is done purposely to increase performance; if
1136  you want function to resize array according to result size, use
1137  function with same name and suffix 'I'.
1138 
1139 SEE ALSO
1140 * KDTreeQueryResultsX() X-values
1141 * KDTreeQueryResultsXY() X- and Y-values
1142 * KDTreeQueryResultsDistances() distances
1143 
1144  -- ALGLIB --
1145  Copyright 28.02.2010 by Bochkanov Sergey
1146 *************************************************************************/
1148 {
1149  alglib_impl::ae_state _alglib_env_state;
1150  alglib_impl::ae_state_init(&_alglib_env_state);
1151  try
1152  {
1153  alglib_impl::kdtreequeryresultstags(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_vector*>(tags.c_ptr()), &_alglib_env_state);
1154  alglib_impl::ae_state_clear(&_alglib_env_state);
1155  return;
1156  }
1158  {
1159  throw ap_error(_alglib_env_state.error_msg);
1160  }
1161 }
1162 
1163 /*************************************************************************
1164 Distances from last query
1165 
1166 INPUT PARAMETERS
1167  KDT - KD-tree
1168  R - possibly pre-allocated buffer. If X is too small to store
1169  result, it is resized. If size(X) is enough to store
1170  result, it is left unchanged.
1171 
1172 OUTPUT PARAMETERS
1173  R - filled with distances (in corresponding norm)
1174 
1175 NOTES
1176 1. points are ordered by distance from the query point (first = closest)
1177 2. if XY is larger than required to store result, only leading part will
1178  be overwritten; trailing part will be left unchanged. So if on input
1179  XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get
1180  XY = [[1,2],[C,D]]. This is done purposely to increase performance; if
1181  you want function to resize array according to result size, use
1182  function with same name and suffix 'I'.
1183 
1184 SEE ALSO
1185 * KDTreeQueryResultsX() X-values
1186 * KDTreeQueryResultsXY() X- and Y-values
1187 * KDTreeQueryResultsTags() tag values
1188 
1189  -- ALGLIB --
1190  Copyright 28.02.2010 by Bochkanov Sergey
1191 *************************************************************************/
1193 {
1194  alglib_impl::ae_state _alglib_env_state;
1195  alglib_impl::ae_state_init(&_alglib_env_state);
1196  try
1197  {
1198  alglib_impl::kdtreequeryresultsdistances(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_vector*>(r.c_ptr()), &_alglib_env_state);
1199  alglib_impl::ae_state_clear(&_alglib_env_state);
1200  return;
1201  }
1203  {
1204  throw ap_error(_alglib_env_state.error_msg);
1205  }
1206 }
1207 
1208 /*************************************************************************
1209 X-values from last query; 'interactive' variant for languages like Python
1210 which support constructs like "X = KDTreeQueryResultsXI(KDT)" and
1211 interactive mode of interpreter.
1212 
1213 This function allocates new array on each call, so it is significantly
1214 slower than its 'non-interactive' counterpart, but it is more convenient
1215 when you call it from command line.
1216 
1217  -- ALGLIB --
1218  Copyright 28.02.2010 by Bochkanov Sergey
1219 *************************************************************************/
1221 {
1222  alglib_impl::ae_state _alglib_env_state;
1223  alglib_impl::ae_state_init(&_alglib_env_state);
1224  try
1225  {
1226  alglib_impl::kdtreequeryresultsxi(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
1227  alglib_impl::ae_state_clear(&_alglib_env_state);
1228  return;
1229  }
1231  {
1232  throw ap_error(_alglib_env_state.error_msg);
1233  }
1234 }
1235 
1236 /*************************************************************************
1237 XY-values from last query; 'interactive' variant for languages like Python
1238 which support constructs like "XY = KDTreeQueryResultsXYI(KDT)" and
1239 interactive mode of interpreter.
1240 
1241 This function allocates new array on each call, so it is significantly
1242 slower than its 'non-interactive' counterpart, but it is more convenient
1243 when you call it from command line.
1244 
1245  -- ALGLIB --
1246  Copyright 28.02.2010 by Bochkanov Sergey
1247 *************************************************************************/
1249 {
1250  alglib_impl::ae_state _alglib_env_state;
1251  alglib_impl::ae_state_init(&_alglib_env_state);
1252  try
1253  {
1254  alglib_impl::kdtreequeryresultsxyi(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.c_ptr()), &_alglib_env_state);
1255  alglib_impl::ae_state_clear(&_alglib_env_state);
1256  return;
1257  }
1259  {
1260  throw ap_error(_alglib_env_state.error_msg);
1261  }
1262 }
1263 
1264 /*************************************************************************
1265 Tags from last query; 'interactive' variant for languages like Python
1266 which support constructs like "Tags = KDTreeQueryResultsTagsI(KDT)" and
1267 interactive mode of interpreter.
1268 
1269 This function allocates new array on each call, so it is significantly
1270 slower than its 'non-interactive' counterpart, but it is more convenient
1271 when you call it from command line.
1272 
1273  -- ALGLIB --
1274  Copyright 28.02.2010 by Bochkanov Sergey
1275 *************************************************************************/
1277 {
1278  alglib_impl::ae_state _alglib_env_state;
1279  alglib_impl::ae_state_init(&_alglib_env_state);
1280  try
1281  {
1282  alglib_impl::kdtreequeryresultstagsi(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_vector*>(tags.c_ptr()), &_alglib_env_state);
1283  alglib_impl::ae_state_clear(&_alglib_env_state);
1284  return;
1285  }
1287  {
1288  throw ap_error(_alglib_env_state.error_msg);
1289  }
1290 }
1291 
1292 /*************************************************************************
1293 Distances from last query; 'interactive' variant for languages like Python
1294 which support constructs like "R = KDTreeQueryResultsDistancesI(KDT)"
1295 and interactive mode of interpreter.
1296 
1297 This function allocates new array on each call, so it is significantly
1298 slower than its 'non-interactive' counterpart, but it is more convenient
1299 when you call it from command line.
1300 
1301  -- ALGLIB --
1302  Copyright 28.02.2010 by Bochkanov Sergey
1303 *************************************************************************/
1305 {
1306  alglib_impl::ae_state _alglib_env_state;
1307  alglib_impl::ae_state_init(&_alglib_env_state);
1308  try
1309  {
1310  alglib_impl::kdtreequeryresultsdistancesi(const_cast<alglib_impl::kdtree*>(kdt.c_ptr()), const_cast<alglib_impl::ae_vector*>(r.c_ptr()), &_alglib_env_state);
1311  alglib_impl::ae_state_clear(&_alglib_env_state);
1312  return;
1313  }
1315  {
1316  throw ap_error(_alglib_env_state.error_msg);
1317  }
1318 }
1319 }
1320 
1322 //
1323 // THIS SECTION CONTAINS IMPLEMENTATION OF COMPUTATIONAL CORE
1324 //
1326 namespace alglib_impl
1327 {
1328 static ae_int_t hqrnd_hqrndmax = 2147483561;
1329 static ae_int_t hqrnd_hqrndm1 = 2147483563;
1330 static ae_int_t hqrnd_hqrndm2 = 2147483399;
1331 static ae_int_t hqrnd_hqrndmagic = 1634357784;
1332 static ae_int_t hqrnd_hqrndintegerbase(hqrndstate* state,
1333  ae_state *_state);
1334 
1335 
1336 static ae_int_t nearestneighbor_splitnodesize = 6;
1337 static ae_int_t nearestneighbor_kdtreefirstversion = 0;
1338 static void nearestneighbor_kdtreesplit(kdtree* kdt,
1339  ae_int_t i1,
1340  ae_int_t i2,
1341  ae_int_t d,
1342  double s,
1343  ae_int_t* i3,
1344  ae_state *_state);
1345 static void nearestneighbor_kdtreegeneratetreerec(kdtree* kdt,
1346  ae_int_t* nodesoffs,
1347  ae_int_t* splitsoffs,
1348  ae_int_t i1,
1349  ae_int_t i2,
1350  ae_int_t maxleafsize,
1351  ae_state *_state);
1352 static void nearestneighbor_kdtreequerynnrec(kdtree* kdt,
1353  ae_int_t offs,
1354  ae_state *_state);
1355 static void nearestneighbor_kdtreeinitbox(kdtree* kdt,
1356  /* Real */ ae_vector* x,
1357  ae_state *_state);
1358 static void nearestneighbor_kdtreeallocdatasetindependent(kdtree* kdt,
1359  ae_int_t nx,
1360  ae_int_t ny,
1361  ae_state *_state);
1362 static void nearestneighbor_kdtreeallocdatasetdependent(kdtree* kdt,
1363  ae_int_t n,
1364  ae_int_t nx,
1365  ae_int_t ny,
1366  ae_state *_state);
1367 static void nearestneighbor_kdtreealloctemporaries(kdtree* kdt,
1368  ae_int_t n,
1369  ae_int_t nx,
1370  ae_int_t ny,
1371  ae_state *_state);
1372 
1373 
1374 
1375 
1376 
1377 /*************************************************************************
1378 HQRNDState initialization with random values which come from standard
1379 RNG.
1380 
1381  -- ALGLIB --
1382  Copyright 02.12.2009 by Bochkanov Sergey
1383 *************************************************************************/
1384 void hqrndrandomize(hqrndstate* state, ae_state *_state)
1385 {
1386  ae_int_t s0;
1387  ae_int_t s1;
1388 
1389  _hqrndstate_clear(state);
1390 
1391  s0 = ae_randominteger(hqrnd_hqrndm1, _state);
1392  s1 = ae_randominteger(hqrnd_hqrndm2, _state);
1393  hqrndseed(s0, s1, state, _state);
1394 }
1395 
1396 
1397 /*************************************************************************
1398 HQRNDState initialization with seed values
1399 
1400  -- ALGLIB --
1401  Copyright 02.12.2009 by Bochkanov Sergey
1402 *************************************************************************/
1404  ae_int_t s2,
1405  hqrndstate* state,
1406  ae_state *_state)
1407 {
1408 
1409  _hqrndstate_clear(state);
1410 
1411 
1412  /*
1413  * Protection against negative seeds:
1414  *
1415  * SEED := -(SEED+1)
1416  *
1417  * We can use just "-SEED" because there exists such integer number N
1418  * that N<0, -N=N<0 too. (This number is equal to 0x800...000). Need
1419  * to handle such seed correctly forces us to use a bit complicated
1420  * formula.
1421  */
1422  if( s1<0 )
1423  {
1424  s1 = -(s1+1);
1425  }
1426  if( s2<0 )
1427  {
1428  s2 = -(s2+1);
1429  }
1430  state->s1 = s1%(hqrnd_hqrndm1-1)+1;
1431  state->s2 = s2%(hqrnd_hqrndm2-1)+1;
1432  state->magicv = hqrnd_hqrndmagic;
1433 }
1434 
1435 
1436 /*************************************************************************
1437 This function generates random real number in (0,1),
1438 not including interval boundaries
1439 
1440 State structure must be initialized with HQRNDRandomize() or HQRNDSeed().
1441 
1442  -- ALGLIB --
1443  Copyright 02.12.2009 by Bochkanov Sergey
1444 *************************************************************************/
1445 double hqrnduniformr(hqrndstate* state, ae_state *_state)
1446 {
1447  double result;
1448 
1449 
1450  result = (double)(hqrnd_hqrndintegerbase(state, _state)+1)/(double)(hqrnd_hqrndmax+2);
1451  return result;
1452 }
1453 
1454 
1455 /*************************************************************************
1456 This function generates random integer number in [0, N)
1457 
1458 1. State structure must be initialized with HQRNDRandomize() or HQRNDSeed()
1459 2. N can be any positive number except for very large numbers:
1460  * close to 2^31 on 32-bit systems
1461  * close to 2^62 on 64-bit systems
1462  An exception will be generated if N is too large.
1463 
1464  -- ALGLIB --
1465  Copyright 02.12.2009 by Bochkanov Sergey
1466 *************************************************************************/
1468 {
1469  ae_int_t maxcnt;
1470  ae_int_t mx;
1471  ae_int_t a;
1472  ae_int_t b;
1473  ae_int_t result;
1474 
1475 
1476  ae_assert(n>0, "HQRNDUniformI: N<=0!", _state);
1477  maxcnt = hqrnd_hqrndmax+1;
1478 
1479  /*
1480  * Two branches: one for N<=MaxCnt, another for N>MaxCnt.
1481  */
1482  if( n>maxcnt )
1483  {
1484 
1485  /*
1486  * N>=MaxCnt.
1487  *
1488  * We have two options here:
1489  * a) N is exactly divisible by MaxCnt
1490  * b) N is not divisible by MaxCnt
1491  *
1492  * In both cases we reduce problem on interval spanning [0,N)
1493  * to several subproblems on intervals spanning [0,MaxCnt).
1494  */
1495  if( n%maxcnt==0 )
1496  {
1497 
1498  /*
1499  * N is exactly divisible by MaxCnt.
1500  *
1501  * [0,N) range is dividided into N/MaxCnt bins,
1502  * each of them having length equal to MaxCnt.
1503  *
1504  * We generate:
1505  * * random bin number B
1506  * * random offset within bin A
1507  * Both random numbers are generated by recursively
1508  * calling HQRNDUniformI().
1509  *
1510  * Result is equal to A+MaxCnt*B.
1511  */
1512  ae_assert(n/maxcnt<=maxcnt, "HQRNDUniformI: N is too large", _state);
1513  a = hqrnduniformi(state, maxcnt, _state);
1514  b = hqrnduniformi(state, n/maxcnt, _state);
1515  result = a+maxcnt*b;
1516  }
1517  else
1518  {
1519 
1520  /*
1521  * N is NOT exactly divisible by MaxCnt.
1522  *
1523  * [0,N) range is dividided into Ceil(N/MaxCnt) bins,
1524  * each of them having length equal to MaxCnt.
1525  *
1526  * We generate:
1527  * * random bin number B in [0, Ceil(N/MaxCnt)-1]
1528  * * random offset within bin A
1529  * * if both of what is below is true
1530  * 1) bin number B is that of the last bin
1531  * 2) A >= N mod MaxCnt
1532  * then we repeat generation of A/B.
1533  * This stage is essential in order to avoid bias in the result.
1534  * * otherwise, we return A*MaxCnt+N
1535  */
1536  ae_assert(n/maxcnt+1<=maxcnt, "HQRNDUniformI: N is too large", _state);
1537  result = -1;
1538  do
1539  {
1540  a = hqrnduniformi(state, maxcnt, _state);
1541  b = hqrnduniformi(state, n/maxcnt+1, _state);
1542  if( b==n/maxcnt&&a>=n%maxcnt )
1543  {
1544  continue;
1545  }
1546  result = a+maxcnt*b;
1547  }
1548  while(result<0);
1549  }
1550  }
1551  else
1552  {
1553 
1554  /*
1555  * N<=MaxCnt
1556  *
1557  * Code below is a bit complicated because we can not simply
1558  * return "HQRNDIntegerBase() mod N" - it will be skewed for
1559  * large N's in [0.1*HQRNDMax...HQRNDMax].
1560  */
1561  mx = maxcnt-maxcnt%n;
1562  do
1563  {
1564  result = hqrnd_hqrndintegerbase(state, _state);
1565  }
1566  while(result>=mx);
1567  result = result%n;
1568  }
1569  return result;
1570 }
1571 
1572 
1573 /*************************************************************************
1574 Random number generator: normal numbers
1575 
1576 This function generates one random number from normal distribution.
1577 Its performance is equal to that of HQRNDNormal2()
1578 
1579 State structure must be initialized with HQRNDRandomize() or HQRNDSeed().
1580 
1581  -- ALGLIB --
1582  Copyright 02.12.2009 by Bochkanov Sergey
1583 *************************************************************************/
1584 double hqrndnormal(hqrndstate* state, ae_state *_state)
1585 {
1586  double v1;
1587  double v2;
1588  double result;
1589 
1590 
1591  hqrndnormal2(state, &v1, &v2, _state);
1592  result = v1;
1593  return result;
1594 }
1595 
1596 
1597 /*************************************************************************
1598 Random number generator: random X and Y such that X^2+Y^2=1
1599 
1600 State structure must be initialized with HQRNDRandomize() or HQRNDSeed().
1601 
1602  -- ALGLIB --
1603  Copyright 02.12.2009 by Bochkanov Sergey
1604 *************************************************************************/
1605 void hqrndunit2(hqrndstate* state, double* x, double* y, ae_state *_state)
1606 {
1607  double v;
1608  double mx;
1609  double mn;
1610 
1611  *x = 0;
1612  *y = 0;
1613 
1614  do
1615  {
1616  hqrndnormal2(state, x, y, _state);
1617  }
1618  while(!(ae_fp_neq(*x,0)||ae_fp_neq(*y,0)));
1619  mx = ae_maxreal(ae_fabs(*x, _state), ae_fabs(*y, _state), _state);
1620  mn = ae_minreal(ae_fabs(*x, _state), ae_fabs(*y, _state), _state);
1621  v = mx*ae_sqrt(1+ae_sqr(mn/mx, _state), _state);
1622  *x = *x/v;
1623  *y = *y/v;
1624 }
1625 
1626 
1627 /*************************************************************************
1628 Random number generator: normal numbers
1629 
1630 This function generates two independent random numbers from normal
1631 distribution. Its performance is equal to that of HQRNDNormal()
1632 
1633 State structure must be initialized with HQRNDRandomize() or HQRNDSeed().
1634 
1635  -- ALGLIB --
1636  Copyright 02.12.2009 by Bochkanov Sergey
1637 *************************************************************************/
1639  double* x1,
1640  double* x2,
1641  ae_state *_state)
1642 {
1643  double u;
1644  double v;
1645  double s;
1646 
1647  *x1 = 0;
1648  *x2 = 0;
1649 
1650  for(;;)
1651  {
1652  u = 2*hqrnduniformr(state, _state)-1;
1653  v = 2*hqrnduniformr(state, _state)-1;
1654  s = ae_sqr(u, _state)+ae_sqr(v, _state);
1655  if( ae_fp_greater(s,0)&&ae_fp_less(s,1) )
1656  {
1657 
1658  /*
1659  * two Sqrt's instead of one to
1660  * avoid overflow when S is too small
1661  */
1662  s = ae_sqrt(-2*ae_log(s, _state), _state)/ae_sqrt(s, _state);
1663  *x1 = u*s;
1664  *x2 = v*s;
1665  return;
1666  }
1667  }
1668 }
1669 
1670 
1671 /*************************************************************************
1672 Random number generator: exponential distribution
1673 
1674 State structure must be initialized with HQRNDRandomize() or HQRNDSeed().
1675 
1676  -- ALGLIB --
1677  Copyright 11.08.2007 by Bochkanov Sergey
1678 *************************************************************************/
1680  double lambdav,
1681  ae_state *_state)
1682 {
1683  double result;
1684 
1685 
1686  ae_assert(ae_fp_greater(lambdav,0), "HQRNDExponential: LambdaV<=0!", _state);
1687  result = -ae_log(hqrnduniformr(state, _state), _state)/lambdav;
1688  return result;
1689 }
1690 
1691 
1692 /*************************************************************************
1693 This function generates random number from discrete distribution given by
1694 finite sample X.
1695 
1696 INPUT PARAMETERS
1697  State - high quality random number generator, must be
1698  initialized with HQRNDRandomize() or HQRNDSeed().
1699  X - finite sample
1700  N - number of elements to use, N>=1
1701 
1702 RESULT
1703  this function returns one of the X[i] for random i=0..N-1
1704 
1705  -- ALGLIB --
1706  Copyright 08.11.2011 by Bochkanov Sergey
1707 *************************************************************************/
1709  /* Real */ ae_vector* x,
1710  ae_int_t n,
1711  ae_state *_state)
1712 {
1713  double result;
1714 
1715 
1716  ae_assert(n>0, "HQRNDDiscrete: N<=0", _state);
1717  ae_assert(n<=x->cnt, "HQRNDDiscrete: Length(X)<N", _state);
1718  result = x->ptr.p_double[hqrnduniformi(state, n, _state)];
1719  return result;
1720 }
1721 
1722 
1723 /*************************************************************************
1724 This function generates random number from continuous distribution given
1725 by finite sample X.
1726 
1727 INPUT PARAMETERS
1728  State - high quality random number generator, must be
1729  initialized with HQRNDRandomize() or HQRNDSeed().
1730  X - finite sample, array[N] (can be larger, in this case only
1731  leading N elements are used). THIS ARRAY MUST BE SORTED BY
1732  ASCENDING.
1733  N - number of elements to use, N>=1
1734 
1735 RESULT
1736  this function returns random number from continuous distribution which
1737  tries to approximate X as mush as possible. min(X)<=Result<=max(X).
1738 
1739  -- ALGLIB --
1740  Copyright 08.11.2011 by Bochkanov Sergey
1741 *************************************************************************/
1743  /* Real */ ae_vector* x,
1744  ae_int_t n,
1745  ae_state *_state)
1746 {
1747  double mx;
1748  double mn;
1749  ae_int_t i;
1750  double result;
1751 
1752 
1753  ae_assert(n>0, "HQRNDContinuous: N<=0", _state);
1754  ae_assert(n<=x->cnt, "HQRNDContinuous: Length(X)<N", _state);
1755  if( n==1 )
1756  {
1757  result = x->ptr.p_double[0];
1758  return result;
1759  }
1760  i = hqrnduniformi(state, n-1, _state);
1761  mn = x->ptr.p_double[i];
1762  mx = x->ptr.p_double[i+1];
1763  ae_assert(ae_fp_greater_eq(mx,mn), "HQRNDDiscrete: X is not sorted by ascending", _state);
1764  if( ae_fp_neq(mx,mn) )
1765  {
1766  result = (mx-mn)*hqrnduniformr(state, _state)+mn;
1767  }
1768  else
1769  {
1770  result = mn;
1771  }
1772  return result;
1773 }
1774 
1775 
1776 /*************************************************************************
1777 This function returns random integer in [0,HQRNDMax]
1778 
1779 L'Ecuyer, Efficient and portable combined random number generators
1780 *************************************************************************/
1781 static ae_int_t hqrnd_hqrndintegerbase(hqrndstate* state,
1782  ae_state *_state)
1783 {
1784  ae_int_t k;
1785  ae_int_t result;
1786 
1787 
1788  ae_assert(state->magicv==hqrnd_hqrndmagic, "HQRNDIntegerBase: State is not correctly initialized!", _state);
1789  k = state->s1/53668;
1790  state->s1 = 40014*(state->s1-k*53668)-k*12211;
1791  if( state->s1<0 )
1792  {
1793  state->s1 = state->s1+2147483563;
1794  }
1795  k = state->s2/52774;
1796  state->s2 = 40692*(state->s2-k*52774)-k*3791;
1797  if( state->s2<0 )
1798  {
1799  state->s2 = state->s2+2147483399;
1800  }
1801 
1802  /*
1803  * Result
1804  */
1805  result = state->s1-state->s2;
1806  if( result<1 )
1807  {
1808  result = result+2147483562;
1809  }
1810  result = result-1;
1811  return result;
1812 }
1813 
1814 
1815 ae_bool _hqrndstate_init(void* _p, ae_state *_state, ae_bool make_automatic)
1816 {
1817  hqrndstate *p = (hqrndstate*)_p;
1818  ae_touch_ptr((void*)p);
1819  return ae_true;
1820 }
1821 
1822 
1823 ae_bool _hqrndstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
1824 {
1825  hqrndstate *dst = (hqrndstate*)_dst;
1826  hqrndstate *src = (hqrndstate*)_src;
1827  dst->s1 = src->s1;
1828  dst->s2 = src->s2;
1829  dst->magicv = src->magicv;
1830  return ae_true;
1831 }
1832 
1833 
1834 void _hqrndstate_clear(void* _p)
1835 {
1836  hqrndstate *p = (hqrndstate*)_p;
1837  ae_touch_ptr((void*)p);
1838 }
1839 
1840 
1841 void _hqrndstate_destroy(void* _p)
1842 {
1843  hqrndstate *p = (hqrndstate*)_p;
1844  ae_touch_ptr((void*)p);
1845 }
1846 
1847 
1848 
1849 
1850 /*************************************************************************
1851 KD-tree creation
1852 
1853 This subroutine creates KD-tree from set of X-values and optional Y-values
1854 
1855 INPUT PARAMETERS
1856  XY - dataset, array[0..N-1,0..NX+NY-1].
1857  one row corresponds to one point.
1858  first NX columns contain X-values, next NY (NY may be zero)
1859  columns may contain associated Y-values
1860  N - number of points, N>=0.
1861  NX - space dimension, NX>=1.
1862  NY - number of optional Y-values, NY>=0.
1863  NormType- norm type:
1864  * 0 denotes infinity-norm
1865  * 1 denotes 1-norm
1866  * 2 denotes 2-norm (Euclidean norm)
1867 
1868 OUTPUT PARAMETERS
1869  KDT - KD-tree
1870 
1871 
1872 NOTES
1873 
1874 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory
1875  requirements.
1876 2. Although KD-trees may be used with any combination of N and NX, they
1877  are more efficient than brute-force search only when N >> 4^NX. So they
1878  are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another
1879  inefficient case, because simple binary search (without additional
1880  structures) is much more efficient in such tasks than KD-trees.
1881 
1882  -- ALGLIB --
1883  Copyright 28.02.2010 by Bochkanov Sergey
1884 *************************************************************************/
1885 void kdtreebuild(/* Real */ ae_matrix* xy,
1886  ae_int_t n,
1887  ae_int_t nx,
1888  ae_int_t ny,
1889  ae_int_t normtype,
1890  kdtree* kdt,
1891  ae_state *_state)
1892 {
1893  ae_frame _frame_block;
1894  ae_vector tags;
1895  ae_int_t i;
1896 
1897  ae_frame_make(_state, &_frame_block);
1898  _kdtree_clear(kdt);
1899  ae_vector_init(&tags, 0, DT_INT, _state, ae_true);
1900 
1901  ae_assert(n>=0, "KDTreeBuild: N<0", _state);
1902  ae_assert(nx>=1, "KDTreeBuild: NX<1", _state);
1903  ae_assert(ny>=0, "KDTreeBuild: NY<0", _state);
1904  ae_assert(normtype>=0&&normtype<=2, "KDTreeBuild: incorrect NormType", _state);
1905  ae_assert(xy->rows>=n, "KDTreeBuild: rows(X)<N", _state);
1906  ae_assert(xy->cols>=nx+ny||n==0, "KDTreeBuild: cols(X)<NX+NY", _state);
1907  ae_assert(apservisfinitematrix(xy, n, nx+ny, _state), "KDTreeBuild: XY contains infinite or NaN values", _state);
1908  if( n>0 )
1909  {
1910  ae_vector_set_length(&tags, n, _state);
1911  for(i=0; i<=n-1; i++)
1912  {
1913  tags.ptr.p_int[i] = 0;
1914  }
1915  }
1916  kdtreebuildtagged(xy, &tags, n, nx, ny, normtype, kdt, _state);
1917  ae_frame_leave(_state);
1918 }
1919 
1920 
1921 /*************************************************************************
1922 KD-tree creation
1923 
1924 This subroutine creates KD-tree from set of X-values, integer tags and
1925 optional Y-values
1926 
1927 INPUT PARAMETERS
1928  XY - dataset, array[0..N-1,0..NX+NY-1].
1929  one row corresponds to one point.
1930  first NX columns contain X-values, next NY (NY may be zero)
1931  columns may contain associated Y-values
1932  Tags - tags, array[0..N-1], contains integer tags associated
1933  with points.
1934  N - number of points, N>=0
1935  NX - space dimension, NX>=1.
1936  NY - number of optional Y-values, NY>=0.
1937  NormType- norm type:
1938  * 0 denotes infinity-norm
1939  * 1 denotes 1-norm
1940  * 2 denotes 2-norm (Euclidean norm)
1941 
1942 OUTPUT PARAMETERS
1943  KDT - KD-tree
1944 
1945 NOTES
1946 
1947 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory
1948  requirements.
1949 2. Although KD-trees may be used with any combination of N and NX, they
1950  are more efficient than brute-force search only when N >> 4^NX. So they
1951  are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another
1952  inefficient case, because simple binary search (without additional
1953  structures) is much more efficient in such tasks than KD-trees.
1954 
1955  -- ALGLIB --
1956  Copyright 28.02.2010 by Bochkanov Sergey
1957 *************************************************************************/
1958 void kdtreebuildtagged(/* Real */ ae_matrix* xy,
1959  /* Integer */ ae_vector* tags,
1960  ae_int_t n,
1961  ae_int_t nx,
1962  ae_int_t ny,
1963  ae_int_t normtype,
1964  kdtree* kdt,
1965  ae_state *_state)
1966 {
1967  ae_int_t i;
1968  ae_int_t j;
1969  ae_int_t maxnodes;
1970  ae_int_t nodesoffs;
1971  ae_int_t splitsoffs;
1972 
1973  _kdtree_clear(kdt);
1974 
1975  ae_assert(n>=0, "KDTreeBuildTagged: N<0", _state);
1976  ae_assert(nx>=1, "KDTreeBuildTagged: NX<1", _state);
1977  ae_assert(ny>=0, "KDTreeBuildTagged: NY<0", _state);
1978  ae_assert(normtype>=0&&normtype<=2, "KDTreeBuildTagged: incorrect NormType", _state);
1979  ae_assert(xy->rows>=n, "KDTreeBuildTagged: rows(X)<N", _state);
1980  ae_assert(xy->cols>=nx+ny||n==0, "KDTreeBuildTagged: cols(X)<NX+NY", _state);
1981  ae_assert(apservisfinitematrix(xy, n, nx+ny, _state), "KDTreeBuildTagged: XY contains infinite or NaN values", _state);
1982 
1983  /*
1984  * initialize
1985  */
1986  kdt->n = n;
1987  kdt->nx = nx;
1988  kdt->ny = ny;
1989  kdt->normtype = normtype;
1990  kdt->kcur = 0;
1991 
1992  /*
1993  * N=0 => quick exit
1994  */
1995  if( n==0 )
1996  {
1997  return;
1998  }
1999 
2000  /*
2001  * Allocate
2002  */
2003  nearestneighbor_kdtreeallocdatasetindependent(kdt, nx, ny, _state);
2004  nearestneighbor_kdtreeallocdatasetdependent(kdt, n, nx, ny, _state);
2005 
2006  /*
2007  * Initial fill
2008  */
2009  for(i=0; i<=n-1; i++)
2010  {
2011  ae_v_move(&kdt->xy.ptr.pp_double[i][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nx-1));
2012  ae_v_move(&kdt->xy.ptr.pp_double[i][nx], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(nx,2*nx+ny-1));
2013  kdt->tags.ptr.p_int[i] = tags->ptr.p_int[i];
2014  }
2015 
2016  /*
2017  * Determine bounding box
2018  */
2019  ae_v_move(&kdt->boxmin.ptr.p_double[0], 1, &kdt->xy.ptr.pp_double[0][0], 1, ae_v_len(0,nx-1));
2020  ae_v_move(&kdt->boxmax.ptr.p_double[0], 1, &kdt->xy.ptr.pp_double[0][0], 1, ae_v_len(0,nx-1));
2021  for(i=1; i<=n-1; i++)
2022  {
2023  for(j=0; j<=nx-1; j++)
2024  {
2025  kdt->boxmin.ptr.p_double[j] = ae_minreal(kdt->boxmin.ptr.p_double[j], kdt->xy.ptr.pp_double[i][j], _state);
2026  kdt->boxmax.ptr.p_double[j] = ae_maxreal(kdt->boxmax.ptr.p_double[j], kdt->xy.ptr.pp_double[i][j], _state);
2027  }
2028  }
2029 
2030  /*
2031  * prepare tree structure
2032  * * MaxNodes=N because we guarantee no trivial splits, i.e.
2033  * every split will generate two non-empty boxes
2034  */
2035  maxnodes = n;
2036  ae_vector_set_length(&kdt->nodes, nearestneighbor_splitnodesize*2*maxnodes, _state);
2037  ae_vector_set_length(&kdt->splits, 2*maxnodes, _state);
2038  nodesoffs = 0;
2039  splitsoffs = 0;
2040  ae_v_move(&kdt->curboxmin.ptr.p_double[0], 1, &kdt->boxmin.ptr.p_double[0], 1, ae_v_len(0,nx-1));
2041  ae_v_move(&kdt->curboxmax.ptr.p_double[0], 1, &kdt->boxmax.ptr.p_double[0], 1, ae_v_len(0,nx-1));
2042  nearestneighbor_kdtreegeneratetreerec(kdt, &nodesoffs, &splitsoffs, 0, n, 8, _state);
2043 }
2044 
2045 
2046 /*************************************************************************
2047 K-NN query: K nearest neighbors
2048 
2049 INPUT PARAMETERS
2050  KDT - KD-tree
2051  X - point, array[0..NX-1].
2052  K - number of neighbors to return, K>=1
2053  SelfMatch - whether self-matches are allowed:
2054  * if True, nearest neighbor may be the point itself
2055  (if it exists in original dataset)
2056  * if False, then only points with non-zero distance
2057  are returned
2058  * if not given, considered True
2059 
2060 RESULT
2061  number of actual neighbors found (either K or N, if K>N).
2062 
2063 This subroutine performs query and stores its result in the internal
2064 structures of the KD-tree. You can use following subroutines to obtain
2065 these results:
2066 * KDTreeQueryResultsX() to get X-values
2067 * KDTreeQueryResultsXY() to get X- and Y-values
2068 * KDTreeQueryResultsTags() to get tag values
2069 * KDTreeQueryResultsDistances() to get distances
2070 
2071  -- ALGLIB --
2072  Copyright 28.02.2010 by Bochkanov Sergey
2073 *************************************************************************/
2075  /* Real */ ae_vector* x,
2076  ae_int_t k,
2077  ae_bool selfmatch,
2078  ae_state *_state)
2079 {
2080  ae_int_t result;
2081 
2082 
2083  ae_assert(k>=1, "KDTreeQueryKNN: K<1!", _state);
2084  ae_assert(x->cnt>=kdt->nx, "KDTreeQueryKNN: Length(X)<NX!", _state);
2085  ae_assert(isfinitevector(x, kdt->nx, _state), "KDTreeQueryKNN: X contains infinite or NaN values!", _state);
2086  result = kdtreequeryaknn(kdt, x, k, selfmatch, 0.0, _state);
2087  return result;
2088 }
2089 
2090 
2091 /*************************************************************************
2092 R-NN query: all points within R-sphere centered at X
2093 
2094 INPUT PARAMETERS
2095  KDT - KD-tree
2096  X - point, array[0..NX-1].
2097  R - radius of sphere (in corresponding norm), R>0
2098  SelfMatch - whether self-matches are allowed:
2099  * if True, nearest neighbor may be the point itself
2100  (if it exists in original dataset)
2101  * if False, then only points with non-zero distance
2102  are returned
2103  * if not given, considered True
2104 
2105 RESULT
2106  number of neighbors found, >=0
2107 
2108 This subroutine performs query and stores its result in the internal
2109 structures of the KD-tree. You can use following subroutines to obtain
2110 actual results:
2111 * KDTreeQueryResultsX() to get X-values
2112 * KDTreeQueryResultsXY() to get X- and Y-values
2113 * KDTreeQueryResultsTags() to get tag values
2114 * KDTreeQueryResultsDistances() to get distances
2115 
2116  -- ALGLIB --
2117  Copyright 28.02.2010 by Bochkanov Sergey
2118 *************************************************************************/
2120  /* Real */ ae_vector* x,
2121  double r,
2122  ae_bool selfmatch,
2123  ae_state *_state)
2124 {
2125  ae_int_t i;
2126  ae_int_t j;
2127  ae_int_t result;
2128 
2129 
2130  ae_assert(ae_fp_greater(r,0), "KDTreeQueryRNN: incorrect R!", _state);
2131  ae_assert(x->cnt>=kdt->nx, "KDTreeQueryRNN: Length(X)<NX!", _state);
2132  ae_assert(isfinitevector(x, kdt->nx, _state), "KDTreeQueryRNN: X contains infinite or NaN values!", _state);
2133 
2134  /*
2135  * Handle special case: KDT.N=0
2136  */
2137  if( kdt->n==0 )
2138  {
2139  kdt->kcur = 0;
2140  result = 0;
2141  return result;
2142  }
2143 
2144  /*
2145  * Prepare parameters
2146  */
2147  kdt->kneeded = 0;
2148  if( kdt->normtype!=2 )
2149  {
2150  kdt->rneeded = r;
2151  }
2152  else
2153  {
2154  kdt->rneeded = ae_sqr(r, _state);
2155  }
2156  kdt->selfmatch = selfmatch;
2157  kdt->approxf = 1;
2158  kdt->kcur = 0;
2159 
2160  /*
2161  * calculate distance from point to current bounding box
2162  */
2163  nearestneighbor_kdtreeinitbox(kdt, x, _state);
2164 
2165  /*
2166  * call recursive search
2167  * results are returned as heap
2168  */
2169  nearestneighbor_kdtreequerynnrec(kdt, 0, _state);
2170 
2171  /*
2172  * pop from heap to generate ordered representation
2173  *
2174  * last element is not pop'ed because it is already in
2175  * its place
2176  */
2177  result = kdt->kcur;
2178  j = kdt->kcur;
2179  for(i=kdt->kcur; i>=2; i--)
2180  {
2181  tagheappopi(&kdt->r, &kdt->idx, &j, _state);
2182  }
2183  return result;
2184 }
2185 
2186 
2187 /*************************************************************************
2188 K-NN query: approximate K nearest neighbors
2189 
2190 INPUT PARAMETERS
2191  KDT - KD-tree
2192  X - point, array[0..NX-1].
2193  K - number of neighbors to return, K>=1
2194  SelfMatch - whether self-matches are allowed:
2195  * if True, nearest neighbor may be the point itself
2196  (if it exists in original dataset)
2197  * if False, then only points with non-zero distance
2198  are returned
2199  * if not given, considered True
2200  Eps - approximation factor, Eps>=0. eps-approximate nearest
2201  neighbor is a neighbor whose distance from X is at
2202  most (1+eps) times distance of true nearest neighbor.
2203 
2204 RESULT
2205  number of actual neighbors found (either K or N, if K>N).
2206 
2207 NOTES
2208  significant performance gain may be achieved only when Eps is is on
2209  the order of magnitude of 1 or larger.
2210 
2211 This subroutine performs query and stores its result in the internal
2212 structures of the KD-tree. You can use following subroutines to obtain
2213 these results:
2214 * KDTreeQueryResultsX() to get X-values
2215 * KDTreeQueryResultsXY() to get X- and Y-values
2216 * KDTreeQueryResultsTags() to get tag values
2217 * KDTreeQueryResultsDistances() to get distances
2218 
2219  -- ALGLIB --
2220  Copyright 28.02.2010 by Bochkanov Sergey
2221 *************************************************************************/
2223  /* Real */ ae_vector* x,
2224  ae_int_t k,
2225  ae_bool selfmatch,
2226  double eps,
2227  ae_state *_state)
2228 {
2229  ae_int_t i;
2230  ae_int_t j;
2231  ae_int_t result;
2232 
2233 
2234  ae_assert(k>0, "KDTreeQueryAKNN: incorrect K!", _state);
2235  ae_assert(ae_fp_greater_eq(eps,0), "KDTreeQueryAKNN: incorrect Eps!", _state);
2236  ae_assert(x->cnt>=kdt->nx, "KDTreeQueryAKNN: Length(X)<NX!", _state);
2237  ae_assert(isfinitevector(x, kdt->nx, _state), "KDTreeQueryAKNN: X contains infinite or NaN values!", _state);
2238 
2239  /*
2240  * Handle special case: KDT.N=0
2241  */
2242  if( kdt->n==0 )
2243  {
2244  kdt->kcur = 0;
2245  result = 0;
2246  return result;
2247  }
2248 
2249  /*
2250  * Prepare parameters
2251  */
2252  k = ae_minint(k, kdt->n, _state);
2253  kdt->kneeded = k;
2254  kdt->rneeded = 0;
2255  kdt->selfmatch = selfmatch;
2256  if( kdt->normtype==2 )
2257  {
2258  kdt->approxf = 1/ae_sqr(1+eps, _state);
2259  }
2260  else
2261  {
2262  kdt->approxf = 1/(1+eps);
2263  }
2264  kdt->kcur = 0;
2265 
2266  /*
2267  * calculate distance from point to current bounding box
2268  */
2269  nearestneighbor_kdtreeinitbox(kdt, x, _state);
2270 
2271  /*
2272  * call recursive search
2273  * results are returned as heap
2274  */
2275  nearestneighbor_kdtreequerynnrec(kdt, 0, _state);
2276 
2277  /*
2278  * pop from heap to generate ordered representation
2279  *
2280  * last element is non pop'ed because it is already in
2281  * its place
2282  */
2283  result = kdt->kcur;
2284  j = kdt->kcur;
2285  for(i=kdt->kcur; i>=2; i--)
2286  {
2287  tagheappopi(&kdt->r, &kdt->idx, &j, _state);
2288  }
2289  return result;
2290 }
2291 
2292 
2293 /*************************************************************************
2294 X-values from last query
2295 
2296 INPUT PARAMETERS
2297  KDT - KD-tree
2298  X - possibly pre-allocated buffer. If X is too small to store
2299  result, it is resized. If size(X) is enough to store
2300  result, it is left unchanged.
2301 
2302 OUTPUT PARAMETERS
2303  X - rows are filled with X-values
2304 
2305 NOTES
2306 1. points are ordered by distance from the query point (first = closest)
2307 2. if XY is larger than required to store result, only leading part will
2308  be overwritten; trailing part will be left unchanged. So if on input
2309  XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get
2310  XY = [[1,2],[C,D]]. This is done purposely to increase performance; if
2311  you want function to resize array according to result size, use
2312  function with same name and suffix 'I'.
2313 
2314 SEE ALSO
2315 * KDTreeQueryResultsXY() X- and Y-values
2316 * KDTreeQueryResultsTags() tag values
2317 * KDTreeQueryResultsDistances() distances
2318 
2319  -- ALGLIB --
2320  Copyright 28.02.2010 by Bochkanov Sergey
2321 *************************************************************************/
2323  /* Real */ ae_matrix* x,
2324  ae_state *_state)
2325 {
2326  ae_int_t i;
2327  ae_int_t k;
2328 
2329 
2330  if( kdt->kcur==0 )
2331  {
2332  return;
2333  }
2334  if( x->rows<kdt->kcur||x->cols<kdt->nx )
2335  {
2336  ae_matrix_set_length(x, kdt->kcur, kdt->nx, _state);
2337  }
2338  k = kdt->kcur;
2339  for(i=0; i<=k-1; i++)
2340  {
2341  ae_v_move(&x->ptr.pp_double[i][0], 1, &kdt->xy.ptr.pp_double[kdt->idx.ptr.p_int[i]][kdt->nx], 1, ae_v_len(0,kdt->nx-1));
2342  }
2343 }
2344 
2345 
2346 /*************************************************************************
2347 X- and Y-values from last query
2348 
2349 INPUT PARAMETERS
2350  KDT - KD-tree
2351  XY - possibly pre-allocated buffer. If XY is too small to store
2352  result, it is resized. If size(XY) is enough to store
2353  result, it is left unchanged.
2354 
2355 OUTPUT PARAMETERS
2356  XY - rows are filled with points: first NX columns with
2357  X-values, next NY columns - with Y-values.
2358 
2359 NOTES
2360 1. points are ordered by distance from the query point (first = closest)
2361 2. if XY is larger than required to store result, only leading part will
2362  be overwritten; trailing part will be left unchanged. So if on input
2363  XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get
2364  XY = [[1,2],[C,D]]. This is done purposely to increase performance; if
2365  you want function to resize array according to result size, use
2366  function with same name and suffix 'I'.
2367 
2368 SEE ALSO
2369 * KDTreeQueryResultsX() X-values
2370 * KDTreeQueryResultsTags() tag values
2371 * KDTreeQueryResultsDistances() distances
2372 
2373  -- ALGLIB --
2374  Copyright 28.02.2010 by Bochkanov Sergey
2375 *************************************************************************/
2377  /* Real */ ae_matrix* xy,
2378  ae_state *_state)
2379 {
2380  ae_int_t i;
2381  ae_int_t k;
2382 
2383 
2384  if( kdt->kcur==0 )
2385  {
2386  return;
2387  }
2388  if( xy->rows<kdt->kcur||xy->cols<kdt->nx+kdt->ny )
2389  {
2390  ae_matrix_set_length(xy, kdt->kcur, kdt->nx+kdt->ny, _state);
2391  }
2392  k = kdt->kcur;
2393  for(i=0; i<=k-1; i++)
2394  {
2395  ae_v_move(&xy->ptr.pp_double[i][0], 1, &kdt->xy.ptr.pp_double[kdt->idx.ptr.p_int[i]][kdt->nx], 1, ae_v_len(0,kdt->nx+kdt->ny-1));
2396  }
2397 }
2398 
2399 
2400 /*************************************************************************
2401 Tags from last query
2402 
2403 INPUT PARAMETERS
2404  KDT - KD-tree
2405  Tags - possibly pre-allocated buffer. If X is too small to store
2406  result, it is resized. If size(X) is enough to store
2407  result, it is left unchanged.
2408 
2409 OUTPUT PARAMETERS
2410  Tags - filled with tags associated with points,
2411  or, when no tags were supplied, with zeros
2412 
2413 NOTES
2414 1. points are ordered by distance from the query point (first = closest)
2415 2. if XY is larger than required to store result, only leading part will
2416  be overwritten; trailing part will be left unchanged. So if on input
2417  XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get
2418  XY = [[1,2],[C,D]]. This is done purposely to increase performance; if
2419  you want function to resize array according to result size, use
2420  function with same name and suffix 'I'.
2421 
2422 SEE ALSO
2423 * KDTreeQueryResultsX() X-values
2424 * KDTreeQueryResultsXY() X- and Y-values
2425 * KDTreeQueryResultsDistances() distances
2426 
2427  -- ALGLIB --
2428  Copyright 28.02.2010 by Bochkanov Sergey
2429 *************************************************************************/
2431  /* Integer */ ae_vector* tags,
2432  ae_state *_state)
2433 {
2434  ae_int_t i;
2435  ae_int_t k;
2436 
2437 
2438  if( kdt->kcur==0 )
2439  {
2440  return;
2441  }
2442  if( tags->cnt<kdt->kcur )
2443  {
2444  ae_vector_set_length(tags, kdt->kcur, _state);
2445  }
2446  k = kdt->kcur;
2447  for(i=0; i<=k-1; i++)
2448  {
2449  tags->ptr.p_int[i] = kdt->tags.ptr.p_int[kdt->idx.ptr.p_int[i]];
2450  }
2451 }
2452 
2453 
2454 /*************************************************************************
2455 Distances from last query
2456 
2457 INPUT PARAMETERS
2458  KDT - KD-tree
2459  R - possibly pre-allocated buffer. If X is too small to store
2460  result, it is resized. If size(X) is enough to store
2461  result, it is left unchanged.
2462 
2463 OUTPUT PARAMETERS
2464  R - filled with distances (in corresponding norm)
2465 
2466 NOTES
2467 1. points are ordered by distance from the query point (first = closest)
2468 2. if XY is larger than required to store result, only leading part will
2469  be overwritten; trailing part will be left unchanged. So if on input
2470  XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get
2471  XY = [[1,2],[C,D]]. This is done purposely to increase performance; if
2472  you want function to resize array according to result size, use
2473  function with same name and suffix 'I'.
2474 
2475 SEE ALSO
2476 * KDTreeQueryResultsX() X-values
2477 * KDTreeQueryResultsXY() X- and Y-values
2478 * KDTreeQueryResultsTags() tag values
2479 
2480  -- ALGLIB --
2481  Copyright 28.02.2010 by Bochkanov Sergey
2482 *************************************************************************/
2484  /* Real */ ae_vector* r,
2485  ae_state *_state)
2486 {
2487  ae_int_t i;
2488  ae_int_t k;
2489 
2490 
2491  if( kdt->kcur==0 )
2492  {
2493  return;
2494  }
2495  if( r->cnt<kdt->kcur )
2496  {
2497  ae_vector_set_length(r, kdt->kcur, _state);
2498  }
2499  k = kdt->kcur;
2500 
2501  /*
2502  * unload norms
2503  *
2504  * Abs() call is used to handle cases with negative norms
2505  * (generated during KFN requests)
2506  */
2507  if( kdt->normtype==0 )
2508  {
2509  for(i=0; i<=k-1; i++)
2510  {
2511  r->ptr.p_double[i] = ae_fabs(kdt->r.ptr.p_double[i], _state);
2512  }
2513  }
2514  if( kdt->normtype==1 )
2515  {
2516  for(i=0; i<=k-1; i++)
2517  {
2518  r->ptr.p_double[i] = ae_fabs(kdt->r.ptr.p_double[i], _state);
2519  }
2520  }
2521  if( kdt->normtype==2 )
2522  {
2523  for(i=0; i<=k-1; i++)
2524  {
2525  r->ptr.p_double[i] = ae_sqrt(ae_fabs(kdt->r.ptr.p_double[i], _state), _state);
2526  }
2527  }
2528 }
2529 
2530 
2531 /*************************************************************************
2532 X-values from last query; 'interactive' variant for languages like Python
2533 which support constructs like "X = KDTreeQueryResultsXI(KDT)" and
2534 interactive mode of interpreter.
2535 
2536 This function allocates new array on each call, so it is significantly
2537 slower than its 'non-interactive' counterpart, but it is more convenient
2538 when you call it from command line.
2539 
2540  -- ALGLIB --
2541  Copyright 28.02.2010 by Bochkanov Sergey
2542 *************************************************************************/
2544  /* Real */ ae_matrix* x,
2545  ae_state *_state)
2546 {
2547 
2548  ae_matrix_clear(x);
2549 
2550  kdtreequeryresultsx(kdt, x, _state);
2551 }
2552 
2553 
2554 /*************************************************************************
2555 XY-values from last query; 'interactive' variant for languages like Python
2556 which support constructs like "XY = KDTreeQueryResultsXYI(KDT)" and
2557 interactive mode of interpreter.
2558 
2559 This function allocates new array on each call, so it is significantly
2560 slower than its 'non-interactive' counterpart, but it is more convenient
2561 when you call it from command line.
2562 
2563  -- ALGLIB --
2564  Copyright 28.02.2010 by Bochkanov Sergey
2565 *************************************************************************/
2567  /* Real */ ae_matrix* xy,
2568  ae_state *_state)
2569 {
2570 
2571  ae_matrix_clear(xy);
2572 
2573  kdtreequeryresultsxy(kdt, xy, _state);
2574 }
2575 
2576 
2577 /*************************************************************************
2578 Tags from last query; 'interactive' variant for languages like Python
2579 which support constructs like "Tags = KDTreeQueryResultsTagsI(KDT)" and
2580 interactive mode of interpreter.
2581 
2582 This function allocates new array on each call, so it is significantly
2583 slower than its 'non-interactive' counterpart, but it is more convenient
2584 when you call it from command line.
2585 
2586  -- ALGLIB --
2587  Copyright 28.02.2010 by Bochkanov Sergey
2588 *************************************************************************/
2590  /* Integer */ ae_vector* tags,
2591  ae_state *_state)
2592 {
2593 
2594  ae_vector_clear(tags);
2595 
2596  kdtreequeryresultstags(kdt, tags, _state);
2597 }
2598 
2599 
2600 /*************************************************************************
2601 Distances from last query; 'interactive' variant for languages like Python
2602 which support constructs like "R = KDTreeQueryResultsDistancesI(KDT)"
2603 and interactive mode of interpreter.
2604 
2605 This function allocates new array on each call, so it is significantly
2606 slower than its 'non-interactive' counterpart, but it is more convenient
2607 when you call it from command line.
2608 
2609  -- ALGLIB --
2610  Copyright 28.02.2010 by Bochkanov Sergey
2611 *************************************************************************/
2613  /* Real */ ae_vector* r,
2614  ae_state *_state)
2615 {
2616 
2617  ae_vector_clear(r);
2618 
2619  kdtreequeryresultsdistances(kdt, r, _state);
2620 }
2621 
2622 
2623 /*************************************************************************
2624 Serializer: allocation
2625 
2626  -- ALGLIB --
2627  Copyright 14.03.2011 by Bochkanov Sergey
2628 *************************************************************************/
2629 void kdtreealloc(ae_serializer* s, kdtree* tree, ae_state *_state)
2630 {
2631 
2632 
2633 
2634  /*
2635  * Header
2636  */
2639 
2640  /*
2641  * Data
2642  */
2647  allocrealmatrix(s, &tree->xy, -1, -1, _state);
2648  allocintegerarray(s, &tree->tags, -1, _state);
2649  allocrealarray(s, &tree->boxmin, -1, _state);
2650  allocrealarray(s, &tree->boxmax, -1, _state);
2651  allocintegerarray(s, &tree->nodes, -1, _state);
2652  allocrealarray(s, &tree->splits, -1, _state);
2653 }
2654 
2655 
2656 /*************************************************************************
2657 Serializer: serialization
2658 
2659  -- ALGLIB --
2660  Copyright 14.03.2011 by Bochkanov Sergey
2661 *************************************************************************/
2663 {
2664 
2665 
2666 
2667  /*
2668  * Header
2669  */
2671  ae_serializer_serialize_int(s, nearestneighbor_kdtreefirstversion, _state);
2672 
2673  /*
2674  * Data
2675  */
2676  ae_serializer_serialize_int(s, tree->n, _state);
2677  ae_serializer_serialize_int(s, tree->nx, _state);
2678  ae_serializer_serialize_int(s, tree->ny, _state);
2679  ae_serializer_serialize_int(s, tree->normtype, _state);
2680  serializerealmatrix(s, &tree->xy, -1, -1, _state);
2681  serializeintegerarray(s, &tree->tags, -1, _state);
2682  serializerealarray(s, &tree->boxmin, -1, _state);
2683  serializerealarray(s, &tree->boxmax, -1, _state);
2684  serializeintegerarray(s, &tree->nodes, -1, _state);
2685  serializerealarray(s, &tree->splits, -1, _state);
2686 }
2687 
2688 
2689 /*************************************************************************
2690 Serializer: unserialization
2691 
2692  -- ALGLIB --
2693  Copyright 14.03.2011 by Bochkanov Sergey
2694 *************************************************************************/
2696 {
2697  ae_int_t i0;
2698  ae_int_t i1;
2699 
2700  _kdtree_clear(tree);
2701 
2702 
2703  /*
2704  * check correctness of header
2705  */
2706  ae_serializer_unserialize_int(s, &i0, _state);
2707  ae_assert(i0==getkdtreeserializationcode(_state), "KDTreeUnserialize: stream header corrupted", _state);
2708  ae_serializer_unserialize_int(s, &i1, _state);
2709  ae_assert(i1==nearestneighbor_kdtreefirstversion, "KDTreeUnserialize: stream header corrupted", _state);
2710 
2711  /*
2712  * Unserialize data
2713  */
2714  ae_serializer_unserialize_int(s, &tree->n, _state);
2715  ae_serializer_unserialize_int(s, &tree->nx, _state);
2716  ae_serializer_unserialize_int(s, &tree->ny, _state);
2717  ae_serializer_unserialize_int(s, &tree->normtype, _state);
2718  unserializerealmatrix(s, &tree->xy, _state);
2719  unserializeintegerarray(s, &tree->tags, _state);
2720  unserializerealarray(s, &tree->boxmin, _state);
2721  unserializerealarray(s, &tree->boxmax, _state);
2722  unserializeintegerarray(s, &tree->nodes, _state);
2723  unserializerealarray(s, &tree->splits, _state);
2724  nearestneighbor_kdtreealloctemporaries(tree, tree->n, tree->nx, tree->ny, _state);
2725 }
2726 
2727 
2728 /*************************************************************************
2729 Rearranges nodes [I1,I2) using partition in D-th dimension with S as threshold.
2730 Returns split position I3: [I1,I3) and [I3,I2) are created as result.
2731 
2732 This subroutine doesn't create tree structures, just rearranges nodes.
2733 *************************************************************************/
2734 static void nearestneighbor_kdtreesplit(kdtree* kdt,
2735  ae_int_t i1,
2736  ae_int_t i2,
2737  ae_int_t d,
2738  double s,
2739  ae_int_t* i3,
2740  ae_state *_state)
2741 {
2742  ae_int_t i;
2743  ae_int_t j;
2744  ae_int_t ileft;
2745  ae_int_t iright;
2746  double v;
2747 
2748  *i3 = 0;
2749 
2750  ae_assert(kdt->n>0, "KDTreeSplit: internal error", _state);
2751 
2752  /*
2753  * split XY/Tags in two parts:
2754  * * [ILeft,IRight] is non-processed part of XY/Tags
2755  *
2756  * After cycle is done, we have Ileft=IRight. We deal with
2757  * this element separately.
2758  *
2759  * After this, [I1,ILeft) contains left part, and [ILeft,I2)
2760  * contains right part.
2761  */
2762  ileft = i1;
2763  iright = i2-1;
2764  while(ileft<iright)
2765  {
2766  if( ae_fp_less_eq(kdt->xy.ptr.pp_double[ileft][d],s) )
2767  {
2768 
2769  /*
2770  * XY[ILeft] is on its place.
2771  * Advance ILeft.
2772  */
2773  ileft = ileft+1;
2774  }
2775  else
2776  {
2777 
2778  /*
2779  * XY[ILeft,..] must be at IRight.
2780  * Swap and advance IRight.
2781  */
2782  for(i=0; i<=2*kdt->nx+kdt->ny-1; i++)
2783  {
2784  v = kdt->xy.ptr.pp_double[ileft][i];
2785  kdt->xy.ptr.pp_double[ileft][i] = kdt->xy.ptr.pp_double[iright][i];
2786  kdt->xy.ptr.pp_double[iright][i] = v;
2787  }
2788  j = kdt->tags.ptr.p_int[ileft];
2789  kdt->tags.ptr.p_int[ileft] = kdt->tags.ptr.p_int[iright];
2790  kdt->tags.ptr.p_int[iright] = j;
2791  iright = iright-1;
2792  }
2793  }
2794  if( ae_fp_less_eq(kdt->xy.ptr.pp_double[ileft][d],s) )
2795  {
2796  ileft = ileft+1;
2797  }
2798  else
2799  {
2800  iright = iright-1;
2801  }
2802  *i3 = ileft;
2803 }
2804 
2805 
2806 /*************************************************************************
2807 Recursive kd-tree generation subroutine.
2808 
2809 PARAMETERS
2810  KDT tree
2811  NodesOffs unused part of Nodes[] which must be filled by tree
2812  SplitsOffs unused part of Splits[]
2813  I1, I2 points from [I1,I2) are processed
2814 
2815 NodesOffs[] and SplitsOffs[] must be large enough.
2816 
2817  -- ALGLIB --
2818  Copyright 28.02.2010 by Bochkanov Sergey
2819 *************************************************************************/
2820 static void nearestneighbor_kdtreegeneratetreerec(kdtree* kdt,
2821  ae_int_t* nodesoffs,
2822  ae_int_t* splitsoffs,
2823  ae_int_t i1,
2824  ae_int_t i2,
2825  ae_int_t maxleafsize,
2826  ae_state *_state)
2827 {
2828  ae_int_t n;
2829  ae_int_t nx;
2830  ae_int_t ny;
2831  ae_int_t i;
2832  ae_int_t j;
2833  ae_int_t oldoffs;
2834  ae_int_t i3;
2835  ae_int_t cntless;
2836  ae_int_t cntgreater;
2837  double minv;
2838  double maxv;
2839  ae_int_t minidx;
2840  ae_int_t maxidx;
2841  ae_int_t d;
2842  double ds;
2843  double s;
2844  double v;
2845  double v0;
2846  double v1;
2847 
2848 
2849  ae_assert(kdt->n>0, "KDTreeGenerateTreeRec: internal error", _state);
2850  ae_assert(i2>i1, "KDTreeGenerateTreeRec: internal error", _state);
2851 
2852  /*
2853  * Generate leaf if needed
2854  */
2855  if( i2-i1<=maxleafsize )
2856  {
2857  kdt->nodes.ptr.p_int[*nodesoffs+0] = i2-i1;
2858  kdt->nodes.ptr.p_int[*nodesoffs+1] = i1;
2859  *nodesoffs = *nodesoffs+2;
2860  return;
2861  }
2862 
2863  /*
2864  * Load values for easier access
2865  */
2866  nx = kdt->nx;
2867  ny = kdt->ny;
2868 
2869  /*
2870  * Select dimension to split:
2871  * * D is a dimension number
2872  * In case bounding box has zero size, we enforce creation of the leaf node.
2873  */
2874  d = 0;
2875  ds = kdt->curboxmax.ptr.p_double[0]-kdt->curboxmin.ptr.p_double[0];
2876  for(i=1; i<=nx-1; i++)
2877  {
2878  v = kdt->curboxmax.ptr.p_double[i]-kdt->curboxmin.ptr.p_double[i];
2879  if( ae_fp_greater(v,ds) )
2880  {
2881  ds = v;
2882  d = i;
2883  }
2884  }
2885  if( ae_fp_eq(ds,0) )
2886  {
2887  kdt->nodes.ptr.p_int[*nodesoffs+0] = i2-i1;
2888  kdt->nodes.ptr.p_int[*nodesoffs+1] = i1;
2889  *nodesoffs = *nodesoffs+2;
2890  return;
2891  }
2892 
2893  /*
2894  * Select split position S using sliding midpoint rule,
2895  * rearrange points into [I1,I3) and [I3,I2).
2896  *
2897  * In case all points has same value of D-th component
2898  * (MinV=MaxV) we enforce D-th dimension of bounding
2899  * box to become exactly zero and repeat tree construction.
2900  */
2901  s = kdt->curboxmin.ptr.p_double[d]+0.5*ds;
2902  ae_v_move(&kdt->buf.ptr.p_double[0], 1, &kdt->xy.ptr.pp_double[i1][d], kdt->xy.stride, ae_v_len(0,i2-i1-1));
2903  n = i2-i1;
2904  cntless = 0;
2905  cntgreater = 0;
2906  minv = kdt->buf.ptr.p_double[0];
2907  maxv = kdt->buf.ptr.p_double[0];
2908  minidx = i1;
2909  maxidx = i1;
2910  for(i=0; i<=n-1; i++)
2911  {
2912  v = kdt->buf.ptr.p_double[i];
2913  if( ae_fp_less(v,minv) )
2914  {
2915  minv = v;
2916  minidx = i1+i;
2917  }
2918  if( ae_fp_greater(v,maxv) )
2919  {
2920  maxv = v;
2921  maxidx = i1+i;
2922  }
2923  if( ae_fp_less(v,s) )
2924  {
2925  cntless = cntless+1;
2926  }
2927  if( ae_fp_greater(v,s) )
2928  {
2929  cntgreater = cntgreater+1;
2930  }
2931  }
2932  if( ae_fp_eq(minv,maxv) )
2933  {
2934 
2935  /*
2936  * In case all points has same value of D-th component
2937  * (MinV=MaxV) we enforce D-th dimension of bounding
2938  * box to become exactly zero and repeat tree construction.
2939  */
2940  v0 = kdt->curboxmin.ptr.p_double[d];
2941  v1 = kdt->curboxmax.ptr.p_double[d];
2942  kdt->curboxmin.ptr.p_double[d] = minv;
2943  kdt->curboxmax.ptr.p_double[d] = maxv;
2944  nearestneighbor_kdtreegeneratetreerec(kdt, nodesoffs, splitsoffs, i1, i2, maxleafsize, _state);
2945  kdt->curboxmin.ptr.p_double[d] = v0;
2946  kdt->curboxmax.ptr.p_double[d] = v1;
2947  return;
2948  }
2949  if( cntless>0&&cntgreater>0 )
2950  {
2951 
2952  /*
2953  * normal midpoint split
2954  */
2955  nearestneighbor_kdtreesplit(kdt, i1, i2, d, s, &i3, _state);
2956  }
2957  else
2958  {
2959 
2960  /*
2961  * sliding midpoint
2962  */
2963  if( cntless==0 )
2964  {
2965 
2966  /*
2967  * 1. move split to MinV,
2968  * 2. place one point to the left bin (move to I1),
2969  * others - to the right bin
2970  */
2971  s = minv;
2972  if( minidx!=i1 )
2973  {
2974  for(i=0; i<=2*nx+ny-1; i++)
2975  {
2976  v = kdt->xy.ptr.pp_double[minidx][i];
2977  kdt->xy.ptr.pp_double[minidx][i] = kdt->xy.ptr.pp_double[i1][i];
2978  kdt->xy.ptr.pp_double[i1][i] = v;
2979  }
2980  j = kdt->tags.ptr.p_int[minidx];
2981  kdt->tags.ptr.p_int[minidx] = kdt->tags.ptr.p_int[i1];
2982  kdt->tags.ptr.p_int[i1] = j;
2983  }
2984  i3 = i1+1;
2985  }
2986  else
2987  {
2988 
2989  /*
2990  * 1. move split to MaxV,
2991  * 2. place one point to the right bin (move to I2-1),
2992  * others - to the left bin
2993  */
2994  s = maxv;
2995  if( maxidx!=i2-1 )
2996  {
2997  for(i=0; i<=2*nx+ny-1; i++)
2998  {
2999  v = kdt->xy.ptr.pp_double[maxidx][i];
3000  kdt->xy.ptr.pp_double[maxidx][i] = kdt->xy.ptr.pp_double[i2-1][i];
3001  kdt->xy.ptr.pp_double[i2-1][i] = v;
3002  }
3003  j = kdt->tags.ptr.p_int[maxidx];
3004  kdt->tags.ptr.p_int[maxidx] = kdt->tags.ptr.p_int[i2-1];
3005  kdt->tags.ptr.p_int[i2-1] = j;
3006  }
3007  i3 = i2-1;
3008  }
3009  }
3010 
3011  /*
3012  * Generate 'split' node
3013  */
3014  kdt->nodes.ptr.p_int[*nodesoffs+0] = 0;
3015  kdt->nodes.ptr.p_int[*nodesoffs+1] = d;
3016  kdt->nodes.ptr.p_int[*nodesoffs+2] = *splitsoffs;
3017  kdt->splits.ptr.p_double[*splitsoffs+0] = s;
3018  oldoffs = *nodesoffs;
3019  *nodesoffs = *nodesoffs+nearestneighbor_splitnodesize;
3020  *splitsoffs = *splitsoffs+1;
3021 
3022  /*
3023  * Recirsive generation:
3024  * * update CurBox
3025  * * call subroutine
3026  * * restore CurBox
3027  */
3028  kdt->nodes.ptr.p_int[oldoffs+3] = *nodesoffs;
3029  v = kdt->curboxmax.ptr.p_double[d];
3030  kdt->curboxmax.ptr.p_double[d] = s;
3031  nearestneighbor_kdtreegeneratetreerec(kdt, nodesoffs, splitsoffs, i1, i3, maxleafsize, _state);
3032  kdt->curboxmax.ptr.p_double[d] = v;
3033  kdt->nodes.ptr.p_int[oldoffs+4] = *nodesoffs;
3034  v = kdt->curboxmin.ptr.p_double[d];
3035  kdt->curboxmin.ptr.p_double[d] = s;
3036  nearestneighbor_kdtreegeneratetreerec(kdt, nodesoffs, splitsoffs, i3, i2, maxleafsize, _state);
3037  kdt->curboxmin.ptr.p_double[d] = v;
3038 }
3039 
3040 
3041 /*************************************************************************
3042 Recursive subroutine for NN queries.
3043 
3044  -- ALGLIB --
3045  Copyright 28.02.2010 by Bochkanov Sergey
3046 *************************************************************************/
3047 static void nearestneighbor_kdtreequerynnrec(kdtree* kdt,
3048  ae_int_t offs,
3049  ae_state *_state)
3050 {
3051  double ptdist;
3052  ae_int_t i;
3053  ae_int_t j;
3054  ae_int_t nx;
3055  ae_int_t i1;
3056  ae_int_t i2;
3057  ae_int_t d;
3058  double s;
3059  double v;
3060  double t1;
3061  ae_int_t childbestoffs;
3062  ae_int_t childworstoffs;
3063  ae_int_t childoffs;
3064  double prevdist;
3065  ae_bool todive;
3066  ae_bool bestisleft;
3067  ae_bool updatemin;
3068 
3069 
3070  ae_assert(kdt->n>0, "KDTreeQueryNNRec: internal error", _state);
3071 
3072  /*
3073  * Leaf node.
3074  * Process points.
3075  */
3076  if( kdt->nodes.ptr.p_int[offs]>0 )
3077  {
3078  i1 = kdt->nodes.ptr.p_int[offs+1];
3079  i2 = i1+kdt->nodes.ptr.p_int[offs];
3080  for(i=i1; i<=i2-1; i++)
3081  {
3082 
3083  /*
3084  * Calculate distance
3085  */
3086  ptdist = 0;
3087  nx = kdt->nx;
3088  if( kdt->normtype==0 )
3089  {
3090  for(j=0; j<=nx-1; j++)
3091  {
3092  ptdist = ae_maxreal(ptdist, ae_fabs(kdt->xy.ptr.pp_double[i][j]-kdt->x.ptr.p_double[j], _state), _state);
3093  }
3094  }
3095  if( kdt->normtype==1 )
3096  {
3097  for(j=0; j<=nx-1; j++)
3098  {
3099  ptdist = ptdist+ae_fabs(kdt->xy.ptr.pp_double[i][j]-kdt->x.ptr.p_double[j], _state);
3100  }
3101  }
3102  if( kdt->normtype==2 )
3103  {
3104  for(j=0; j<=nx-1; j++)
3105  {
3106  ptdist = ptdist+ae_sqr(kdt->xy.ptr.pp_double[i][j]-kdt->x.ptr.p_double[j], _state);
3107  }
3108  }
3109 
3110  /*
3111  * Skip points with zero distance if self-matches are turned off
3112  */
3113  if( ae_fp_eq(ptdist,0)&&!kdt->selfmatch )
3114  {
3115  continue;
3116  }
3117 
3118  /*
3119  * We CAN'T process point if R-criterion isn't satisfied,
3120  * i.e. (RNeeded<>0) AND (PtDist>R).
3121  */
3122  if( ae_fp_eq(kdt->rneeded,0)||ae_fp_less_eq(ptdist,kdt->rneeded) )
3123  {
3124 
3125  /*
3126  * R-criterion is satisfied, we must either:
3127  * * replace worst point, if (KNeeded<>0) AND (KCur=KNeeded)
3128  * (or skip, if worst point is better)
3129  * * add point without replacement otherwise
3130  */
3131  if( kdt->kcur<kdt->kneeded||kdt->kneeded==0 )
3132  {
3133 
3134  /*
3135  * add current point to heap without replacement
3136  */
3137  tagheappushi(&kdt->r, &kdt->idx, &kdt->kcur, ptdist, i, _state);
3138  }
3139  else
3140  {
3141 
3142  /*
3143  * New points are added or not, depending on their distance.
3144  * If added, they replace element at the top of the heap
3145  */
3146  if( ae_fp_less(ptdist,kdt->r.ptr.p_double[0]) )
3147  {
3148  if( kdt->kneeded==1 )
3149  {
3150  kdt->idx.ptr.p_int[0] = i;
3151  kdt->r.ptr.p_double[0] = ptdist;
3152  }
3153  else
3154  {
3155  tagheapreplacetopi(&kdt->r, &kdt->idx, kdt->kneeded, ptdist, i, _state);
3156  }
3157  }
3158  }
3159  }
3160  }
3161  return;
3162  }
3163 
3164  /*
3165  * Simple split
3166  */
3167  if( kdt->nodes.ptr.p_int[offs]==0 )
3168  {
3169 
3170  /*
3171  * Load:
3172  * * D dimension to split
3173  * * S split position
3174  */
3175  d = kdt->nodes.ptr.p_int[offs+1];
3176  s = kdt->splits.ptr.p_double[kdt->nodes.ptr.p_int[offs+2]];
3177 
3178  /*
3179  * Calculate:
3180  * * ChildBestOffs child box with best chances
3181  * * ChildWorstOffs child box with worst chances
3182  */
3183  if( ae_fp_less_eq(kdt->x.ptr.p_double[d],s) )
3184  {
3185  childbestoffs = kdt->nodes.ptr.p_int[offs+3];
3186  childworstoffs = kdt->nodes.ptr.p_int[offs+4];
3187  bestisleft = ae_true;
3188  }
3189  else
3190  {
3191  childbestoffs = kdt->nodes.ptr.p_int[offs+4];
3192  childworstoffs = kdt->nodes.ptr.p_int[offs+3];
3193  bestisleft = ae_false;
3194  }
3195 
3196  /*
3197  * Navigate through childs
3198  */
3199  for(i=0; i<=1; i++)
3200  {
3201 
3202  /*
3203  * Select child to process:
3204  * * ChildOffs current child offset in Nodes[]
3205  * * UpdateMin whether minimum or maximum value
3206  * of bounding box is changed on update
3207  */
3208  if( i==0 )
3209  {
3210  childoffs = childbestoffs;
3211  updatemin = !bestisleft;
3212  }
3213  else
3214  {
3215  updatemin = bestisleft;
3216  childoffs = childworstoffs;
3217  }
3218 
3219  /*
3220  * Update bounding box and current distance
3221  */
3222  if( updatemin )
3223  {
3224  prevdist = kdt->curdist;
3225  t1 = kdt->x.ptr.p_double[d];
3226  v = kdt->curboxmin.ptr.p_double[d];
3227  if( ae_fp_less_eq(t1,s) )
3228  {
3229  if( kdt->normtype==0 )
3230  {
3231  kdt->curdist = ae_maxreal(kdt->curdist, s-t1, _state);
3232  }
3233  if( kdt->normtype==1 )
3234  {
3235  kdt->curdist = kdt->curdist-ae_maxreal(v-t1, 0, _state)+s-t1;
3236  }
3237  if( kdt->normtype==2 )
3238  {
3239  kdt->curdist = kdt->curdist-ae_sqr(ae_maxreal(v-t1, 0, _state), _state)+ae_sqr(s-t1, _state);
3240  }
3241  }
3242  kdt->curboxmin.ptr.p_double[d] = s;
3243  }
3244  else
3245  {
3246  prevdist = kdt->curdist;
3247  t1 = kdt->x.ptr.p_double[d];
3248  v = kdt->curboxmax.ptr.p_double[d];
3249  if( ae_fp_greater_eq(t1,s) )
3250  {
3251  if( kdt->normtype==0 )
3252  {
3253  kdt->curdist = ae_maxreal(kdt->curdist, t1-s, _state);
3254  }
3255  if( kdt->normtype==1 )
3256  {
3257  kdt->curdist = kdt->curdist-ae_maxreal(t1-v, 0, _state)+t1-s;
3258  }
3259  if( kdt->normtype==2 )
3260  {
3261  kdt->curdist = kdt->curdist-ae_sqr(ae_maxreal(t1-v, 0, _state), _state)+ae_sqr(t1-s, _state);
3262  }
3263  }
3264  kdt->curboxmax.ptr.p_double[d] = s;
3265  }
3266 
3267  /*
3268  * Decide: to dive into cell or not to dive
3269  */
3270  if( ae_fp_neq(kdt->rneeded,0)&&ae_fp_greater(kdt->curdist,kdt->rneeded) )
3271  {
3272  todive = ae_false;
3273  }
3274  else
3275  {
3276  if( kdt->kcur<kdt->kneeded||kdt->kneeded==0 )
3277  {
3278 
3279  /*
3280  * KCur<KNeeded (i.e. not all points are found)
3281  */
3282  todive = ae_true;
3283  }
3284  else
3285  {
3286 
3287  /*
3288  * KCur=KNeeded, decide to dive or not to dive
3289  * using point position relative to bounding box.
3290  */
3291  todive = ae_fp_less_eq(kdt->curdist,kdt->r.ptr.p_double[0]*kdt->approxf);
3292  }
3293  }
3294  if( todive )
3295  {
3296  nearestneighbor_kdtreequerynnrec(kdt, childoffs, _state);
3297  }
3298 
3299  /*
3300  * Restore bounding box and distance
3301  */
3302  if( updatemin )
3303  {
3304  kdt->curboxmin.ptr.p_double[d] = v;
3305  }
3306  else
3307  {
3308  kdt->curboxmax.ptr.p_double[d] = v;
3309  }
3310  kdt->curdist = prevdist;
3311  }
3312  return;
3313  }
3314 }
3315 
3316 
3317 /*************************************************************************
3318 Copies X[] to KDT.X[]
3319 Loads distance from X[] to bounding box.
3320 Initializes CurBox[].
3321 
3322  -- ALGLIB --
3323  Copyright 28.02.2010 by Bochkanov Sergey
3324 *************************************************************************/
3325 static void nearestneighbor_kdtreeinitbox(kdtree* kdt,
3326  /* Real */ ae_vector* x,
3327  ae_state *_state)
3328 {
3329  ae_int_t i;
3330  double vx;
3331  double vmin;
3332  double vmax;
3333 
3334 
3335  ae_assert(kdt->n>0, "KDTreeInitBox: internal error", _state);
3336 
3337  /*
3338  * calculate distance from point to current bounding box
3339  */
3340  kdt->curdist = 0;
3341  if( kdt->normtype==0 )
3342  {
3343  for(i=0; i<=kdt->nx-1; i++)
3344  {
3345  vx = x->ptr.p_double[i];
3346  vmin = kdt->boxmin.ptr.p_double[i];
3347  vmax = kdt->boxmax.ptr.p_double[i];
3348  kdt->x.ptr.p_double[i] = vx;
3349  kdt->curboxmin.ptr.p_double[i] = vmin;
3350  kdt->curboxmax.ptr.p_double[i] = vmax;
3351  if( ae_fp_less(vx,vmin) )
3352  {
3353  kdt->curdist = ae_maxreal(kdt->curdist, vmin-vx, _state);
3354  }
3355  else
3356  {
3357  if( ae_fp_greater(vx,vmax) )
3358  {
3359  kdt->curdist = ae_maxreal(kdt->curdist, vx-vmax, _state);
3360  }
3361  }
3362  }
3363  }
3364  if( kdt->normtype==1 )
3365  {
3366  for(i=0; i<=kdt->nx-1; i++)
3367  {
3368  vx = x->ptr.p_double[i];
3369  vmin = kdt->boxmin.ptr.p_double[i];
3370  vmax = kdt->boxmax.ptr.p_double[i];
3371  kdt->x.ptr.p_double[i] = vx;
3372  kdt->curboxmin.ptr.p_double[i] = vmin;
3373  kdt->curboxmax.ptr.p_double[i] = vmax;
3374  if( ae_fp_less(vx,vmin) )
3375  {
3376  kdt->curdist = kdt->curdist+vmin-vx;
3377  }
3378  else
3379  {
3380  if( ae_fp_greater(vx,vmax) )
3381  {
3382  kdt->curdist = kdt->curdist+vx-vmax;
3383  }
3384  }
3385  }
3386  }
3387  if( kdt->normtype==2 )
3388  {
3389  for(i=0; i<=kdt->nx-1; i++)
3390  {
3391  vx = x->ptr.p_double[i];
3392  vmin = kdt->boxmin.ptr.p_double[i];
3393  vmax = kdt->boxmax.ptr.p_double[i];
3394  kdt->x.ptr.p_double[i] = vx;
3395  kdt->curboxmin.ptr.p_double[i] = vmin;
3396  kdt->curboxmax.ptr.p_double[i] = vmax;
3397  if( ae_fp_less(vx,vmin) )
3398  {
3399  kdt->curdist = kdt->curdist+ae_sqr(vmin-vx, _state);
3400  }
3401  else
3402  {
3403  if( ae_fp_greater(vx,vmax) )
3404  {
3405  kdt->curdist = kdt->curdist+ae_sqr(vx-vmax, _state);
3406  }
3407  }
3408  }
3409  }
3410 }
3411 
3412 
3413 /*************************************************************************
3414 This function allocates all dataset-independent array fields of KDTree,
3415 i.e. such array fields that their dimensions do not depend on dataset
3416 size.
3417 
3418 This function do not sets KDT.NX or KDT.NY - it just allocates arrays
3419 
3420  -- ALGLIB --
3421  Copyright 14.03.2011 by Bochkanov Sergey
3422 *************************************************************************/
3423 static void nearestneighbor_kdtreeallocdatasetindependent(kdtree* kdt,
3424  ae_int_t nx,
3425  ae_int_t ny,
3426  ae_state *_state)
3427 {
3428 
3429 
3430  ae_assert(kdt->n>0, "KDTreeAllocDatasetIndependent: internal error", _state);
3431  ae_vector_set_length(&kdt->x, nx, _state);
3432  ae_vector_set_length(&kdt->boxmin, nx, _state);
3433  ae_vector_set_length(&kdt->boxmax, nx, _state);
3434  ae_vector_set_length(&kdt->curboxmin, nx, _state);
3435  ae_vector_set_length(&kdt->curboxmax, nx, _state);
3436 }
3437 
3438 
3439 /*************************************************************************
3440 This function allocates all dataset-dependent array fields of KDTree, i.e.
3441 such array fields that their dimensions depend on dataset size.
3442 
3443 This function do not sets KDT.N, KDT.NX or KDT.NY -
3444 it just allocates arrays.
3445 
3446  -- ALGLIB --
3447  Copyright 14.03.2011 by Bochkanov Sergey
3448 *************************************************************************/
3449 static void nearestneighbor_kdtreeallocdatasetdependent(kdtree* kdt,
3450  ae_int_t n,
3451  ae_int_t nx,
3452  ae_int_t ny,
3453  ae_state *_state)
3454 {
3455 
3456 
3457  ae_assert(n>0, "KDTreeAllocDatasetDependent: internal error", _state);
3458  ae_matrix_set_length(&kdt->xy, n, 2*nx+ny, _state);
3459  ae_vector_set_length(&kdt->tags, n, _state);
3460  ae_vector_set_length(&kdt->idx, n, _state);
3461  ae_vector_set_length(&kdt->r, n, _state);
3462  ae_vector_set_length(&kdt->x, nx, _state);
3463  ae_vector_set_length(&kdt->buf, ae_maxint(n, nx, _state), _state);
3464  ae_vector_set_length(&kdt->nodes, nearestneighbor_splitnodesize*2*n, _state);
3465  ae_vector_set_length(&kdt->splits, 2*n, _state);
3466 }
3467 
3468 
3469 /*************************************************************************
3470 This function allocates temporaries.
3471 
3472 This function do not sets KDT.N, KDT.NX or KDT.NY -
3473 it just allocates arrays.
3474 
3475  -- ALGLIB --
3476  Copyright 14.03.2011 by Bochkanov Sergey
3477 *************************************************************************/
3478 static void nearestneighbor_kdtreealloctemporaries(kdtree* kdt,
3479  ae_int_t n,
3480  ae_int_t nx,
3481  ae_int_t ny,
3482  ae_state *_state)
3483 {
3484 
3485 
3486  ae_assert(n>0, "KDTreeAllocTemporaries: internal error", _state);
3487  ae_vector_set_length(&kdt->x, nx, _state);
3488  ae_vector_set_length(&kdt->idx, n, _state);
3489  ae_vector_set_length(&kdt->r, n, _state);
3490  ae_vector_set_length(&kdt->buf, ae_maxint(n, nx, _state), _state);
3491  ae_vector_set_length(&kdt->curboxmin, nx, _state);
3492  ae_vector_set_length(&kdt->curboxmax, nx, _state);
3493 }
3494 
3495 
3496 ae_bool _kdtree_init(void* _p, ae_state *_state, ae_bool make_automatic)
3497 {
3498  kdtree *p = (kdtree*)_p;
3499  ae_touch_ptr((void*)p);
3500  if( !ae_matrix_init(&p->xy, 0, 0, DT_REAL, _state, make_automatic) )
3501  return ae_false;
3502  if( !ae_vector_init(&p->tags, 0, DT_INT, _state, make_automatic) )
3503  return ae_false;
3504  if( !ae_vector_init(&p->boxmin, 0, DT_REAL, _state, make_automatic) )
3505  return ae_false;
3506  if( !ae_vector_init(&p->boxmax, 0, DT_REAL, _state, make_automatic) )
3507  return ae_false;
3508  if( !ae_vector_init(&p->nodes, 0, DT_INT, _state, make_automatic) )
3509  return ae_false;
3510  if( !ae_vector_init(&p->splits, 0, DT_REAL, _state, make_automatic) )
3511  return ae_false;
3512  if( !ae_vector_init(&p->x, 0, DT_REAL, _state, make_automatic) )
3513  return ae_false;
3514  if( !ae_vector_init(&p->idx, 0, DT_INT, _state, make_automatic) )
3515  return ae_false;
3516  if( !ae_vector_init(&p->r, 0, DT_REAL, _state, make_automatic) )
3517  return ae_false;
3518  if( !ae_vector_init(&p->buf, 0, DT_REAL, _state, make_automatic) )
3519  return ae_false;
3520  if( !ae_vector_init(&p->curboxmin, 0, DT_REAL, _state, make_automatic) )
3521  return ae_false;
3522  if( !ae_vector_init(&p->curboxmax, 0, DT_REAL, _state, make_automatic) )
3523  return ae_false;
3524  return ae_true;
3525 }
3526 
3527 
3528 ae_bool _kdtree_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
3529 {
3530  kdtree *dst = (kdtree*)_dst;
3531  kdtree *src = (kdtree*)_src;
3532  dst->n = src->n;
3533  dst->nx = src->nx;
3534  dst->ny = src->ny;
3535  dst->normtype = src->normtype;
3536  if( !ae_matrix_init_copy(&dst->xy, &src->xy, _state, make_automatic) )
3537  return ae_false;
3538  if( !ae_vector_init_copy(&dst->tags, &src->tags, _state, make_automatic) )
3539  return ae_false;
3540  if( !ae_vector_init_copy(&dst->boxmin, &src->boxmin, _state, make_automatic) )
3541  return ae_false;
3542  if( !ae_vector_init_copy(&dst->boxmax, &src->boxmax, _state, make_automatic) )
3543  return ae_false;
3544  if( !ae_vector_init_copy(&dst->nodes, &src->nodes, _state, make_automatic) )
3545  return ae_false;
3546  if( !ae_vector_init_copy(&dst->splits, &src->splits, _state, make_automatic) )
3547  return ae_false;
3548  if( !ae_vector_init_copy(&dst->x, &src->x, _state, make_automatic) )
3549  return ae_false;
3550  dst->kneeded = src->kneeded;
3551  dst->rneeded = src->rneeded;
3552  dst->selfmatch = src->selfmatch;
3553  dst->approxf = src->approxf;
3554  dst->kcur = src->kcur;
3555  if( !ae_vector_init_copy(&dst->idx, &src->idx, _state, make_automatic) )
3556  return ae_false;
3557  if( !ae_vector_init_copy(&dst->r, &src->r, _state, make_automatic) )
3558  return ae_false;
3559  if( !ae_vector_init_copy(&dst->buf, &src->buf, _state, make_automatic) )
3560  return ae_false;
3561  if( !ae_vector_init_copy(&dst->curboxmin, &src->curboxmin, _state, make_automatic) )
3562  return ae_false;
3563  if( !ae_vector_init_copy(&dst->curboxmax, &src->curboxmax, _state, make_automatic) )
3564  return ae_false;
3565  dst->curdist = src->curdist;
3566  dst->debugcounter = src->debugcounter;
3567  return ae_true;
3568 }
3569 
3570 
3571 void _kdtree_clear(void* _p)
3572 {
3573  kdtree *p = (kdtree*)_p;
3574  ae_touch_ptr((void*)p);
3575  ae_matrix_clear(&p->xy);
3576  ae_vector_clear(&p->tags);
3577  ae_vector_clear(&p->boxmin);
3578  ae_vector_clear(&p->boxmax);
3579  ae_vector_clear(&p->nodes);
3580  ae_vector_clear(&p->splits);
3581  ae_vector_clear(&p->x);
3582  ae_vector_clear(&p->idx);
3583  ae_vector_clear(&p->r);
3584  ae_vector_clear(&p->buf);
3585  ae_vector_clear(&p->curboxmin);
3586  ae_vector_clear(&p->curboxmax);
3587 }
3588 
3589 
3590 void _kdtree_destroy(void* _p)
3591 {
3592  kdtree *p = (kdtree*)_p;
3593  ae_touch_ptr((void*)p);
3594  ae_matrix_destroy(&p->xy);
3595  ae_vector_destroy(&p->tags);
3596  ae_vector_destroy(&p->boxmin);
3597  ae_vector_destroy(&p->boxmax);
3598  ae_vector_destroy(&p->nodes);
3599  ae_vector_destroy(&p->splits);
3600  ae_vector_destroy(&p->x);
3601  ae_vector_destroy(&p->idx);
3602  ae_vector_destroy(&p->r);
3603  ae_vector_destroy(&p->buf);
3604  ae_vector_destroy(&p->curboxmin);
3605  ae_vector_destroy(&p->curboxmax);
3606 }
3607 
3608 
3609 
3610 }
3611 
struct alglib_impl::ae_state ae_state
void kdtreeserialize(ae_serializer *s, kdtree *tree, ae_state *_state)
ae_bool ae_fp_greater_eq(double v1, double v2)
Definition: ap.cpp:1351
kdtree & operator=(const kdtree &rhs)
Definition: alglibmisc.cpp:434
void ae_serializer_init(ae_serializer *serializer)
Definition: ap.cpp:3393
void _hqrndstate_clear(void *_p)
void serializerealarray(ae_serializer *s, ae_vector *v, ae_int_t n, ae_state *_state)
void kdtreequeryresultsxi(kdtree *kdt, ae_matrix *x, ae_state *_state)
ae_int_t cols
Definition: ap.h:445
ae_vector curboxmin
Definition: alglibmisc.h:58
void kdtreequeryresultstagsi(const kdtree &kdt, integer_1d_array &tags)
ae_int_t ae_serializer_get_alloc_size(ae_serializer *serializer)
Definition: ap.cpp:3416
void ae_serializer_sstart_str(ae_serializer *serializer, std::string *buf)
Definition: ap.cpp:3447
ae_int_t kdtreequeryaknn(kdtree *kdt, ae_vector *x, ae_int_t k, ae_bool selfmatch, double eps, ae_state *_state)
void kdtreequeryresultsdistancesi(kdtree *kdt, ae_vector *r, ae_state *_state)
void kdtreequeryresultsx(const kdtree &kdt, real_2d_array &x)
double ae_fabs(double x, ae_state *state)
Definition: ap.cpp:1520
void kdtreebuild(const real_2d_array &xy, const ae_int_t n, const ae_int_t nx, const ae_int_t ny, const ae_int_t normtype, kdtree &kdt)
Definition: alglibmisc.cpp:554
double hqrnduniformr(const hqrndstate &state)
Definition: alglibmisc.cpp:167
#define ae_false
Definition: ap.h:196
void * ae_malloc(size_t size, ae_state *state)
Definition: ap.cpp:222
ae_int_t stride
Definition: ap.h:446
void kdtreequeryresultsdistances(const kdtree &kdt, real_1d_array &r)
alglib_impl::hqrndstate * c_ptr()
Definition: alglibmisc.cpp:84
double hqrndcontinuous(hqrndstate *state, ae_vector *x, ae_int_t n, ae_state *_state)
double hqrnddiscrete(hqrndstate *state, ae_vector *x, ae_int_t n, ae_state *_state)
union alglib_impl::ae_matrix::@12 ptr
ae_vector splits
Definition: alglibmisc.h:48
void ae_frame_make(ae_state *state, ae_frame *tmp)
Definition: ap.cpp:402
static double * y
void hqrndnormal2(hqrndstate *state, double *x1, double *x2, ae_state *_state)
double hqrndexponential(hqrndstate *state, double lambdav, ae_state *_state)
ae_int_t hqrnduniformi(hqrndstate *state, ae_int_t n, ae_state *_state)
void kdtreequeryresultstags(const kdtree &kdt, integer_1d_array &tags)
void kdtreealloc(ae_serializer *s, kdtree *tree, ae_state *_state)
alglib_impl::kdtree * p_struct
Definition: alglibmisc.h:119
ae_vector boxmax
Definition: alglibmisc.h:46
virtual ~hqrndstate()
Definition: alglibmisc.cpp:109
ae_bool apservisfinitematrix(ae_matrix *x, ae_int_t m, ae_int_t n, ae_state *_state)
void kdtreebuildtagged(const real_2d_array &xy, const integer_1d_array &tags, const ae_int_t n, const ae_int_t nx, const ae_int_t ny, const ae_int_t normtype, kdtree &kdt)
Definition: alglibmisc.cpp:662
void ae_serializer_ustart_str(ae_serializer *serializer, const std::string *buf)
Definition: ap.cpp:3457
alglib_impl::hqrndstate * p_struct
Definition: alglibmisc.h:94
ae_int_t kdtreequeryknn(const kdtree &kdt, const real_1d_array &x, const ae_int_t k, const bool selfmatch)
Definition: alglibmisc.cpp:764
double * p_double
Definition: ap.h:437
alglib_impl::kdtree * c_ptr()
Definition: alglibmisc.cpp:417
void serializeintegerarray(ae_serializer *s, ae_vector *v, ae_int_t n, ae_state *_state)
void ae_serializer_stop(ae_serializer *serializer)
Definition: ap.cpp:3599
void allocrealarray(ae_serializer *s, ae_vector *v, ae_int_t n, ae_state *_state)
void ae_state_clear(ae_state *state)
Definition: ap.cpp:373
const alglib_impl::ae_matrix * c_ptr() const
Definition: ap.cpp:6463
ae_bool ae_fp_eq(double v1, double v2)
Definition: ap.cpp:1313
void kdtreequeryresultsxyi(const kdtree &kdt, real_2d_array &xy)
cmache_1 eps
void kdtreequeryresultsxyi(kdtree *kdt, ae_matrix *xy, ae_state *_state)
ae_int_t getkdtreeserializationcode(ae_state *_state)
void hqrndnormal2(const hqrndstate &state, double &x1, double &x2)
Definition: alglibmisc.cpp:273
void unserializerealmatrix(ae_serializer *s, ae_matrix *v, ae_state *_state)
void unserializerealarray(ae_serializer *s, ae_vector *v, ae_state *_state)
void hqrndseed(const ae_int_t s1, const ae_int_t s2, hqrndstate &state)
Definition: alglibmisc.cpp:142
void allocintegerarray(ae_serializer *s, ae_vector *v, ae_int_t n, ae_state *_state)
ae_bool ae_matrix_init_copy(ae_matrix *dst, ae_matrix *src, ae_state *state, ae_bool make_automatic)
Definition: ap.cpp:801
ae_bool ae_matrix_init(ae_matrix *dst, ae_int_t rows, ae_int_t cols, ae_datatype datatype, ae_state *state, ae_bool make_automatic)
Definition: ap.cpp:756
doublereal * x
void ae_matrix_destroy(ae_matrix *dst)
Definition: ap.cpp:909
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
ae_vector boxmin
Definition: alglibmisc.h:45
ae_bool _kdtree_init(void *_p, ae_state *_state, ae_bool make_automatic)
doublereal * d
double hqrndexponential(const hqrndstate &state, const double lambdav)
Definition: alglibmisc.cpp:297
void ae_serializer_clear(ae_serializer *serializer)
Definition: ap.cpp:3400
ae_int_t kdtreequeryknn(kdtree *kdt, ae_vector *x, ae_int_t k, ae_bool selfmatch, ae_state *_state)
ae_int_t kdtreequeryaknn(const kdtree &kdt, const real_1d_array &x, const ae_int_t k, const bool selfmatch, const double eps)
Definition: alglibmisc.cpp:955
ae_bool _kdtree_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void kdtreequeryresultsdistances(kdtree *kdt, ae_vector *r, ae_state *_state)
double hqrnduniformr(hqrndstate *state, ae_state *_state)
void kdtreequeryresultsxi(const kdtree &kdt, real_2d_array &x)
double hqrnddiscrete(const hqrndstate &state, const real_1d_array &x, const ae_int_t n)
Definition: alglibmisc.cpp:329
void ae_serializer_serialize_int(ae_serializer *serializer, ae_int_t v, ae_state *state)
Definition: ap.cpp:3514
void kdtreeunserialize(std::string &s_in, kdtree &obj)
Definition: alglibmisc.cpp:498
ae_int_t ae_randominteger(ae_int_t maxv, ae_state *state)
Definition: ap.cpp:1621
ae_int_t ae_v_len(ae_int_t a, ae_int_t b)
Definition: ap.cpp:4562
void ae_vector_destroy(ae_vector *dst)
Definition: ap.cpp:707
void hqrndseed(ae_int_t s1, ae_int_t s2, hqrndstate *state, ae_state *_state)
doublereal * b
ae_int_t hqrnduniformi(const hqrndstate &state, const ae_int_t n)
Definition: alglibmisc.cpp:195
double v1
void kdtreequeryresultstags(kdtree *kdt, ae_vector *tags, ae_state *_state)
void kdtreequeryresultsdistancesi(const kdtree &kdt, real_1d_array &r)
ae_int_t kdtreequeryrnn(kdtree *kdt, ae_vector *x, double r, ae_bool selfmatch, ae_state *_state)
void ae_v_move(double *vdst, ae_int_t stride_dst, const double *vsrc, ae_int_t stride_src, ae_int_t n)
Definition: ap.cpp:4371
ae_int_t rows
Definition: ap.h:444
void ae_vector_clear(ae_vector *dst)
Definition: ap.cpp:692
ae_int_t length() const
Definition: ap.cpp:5882
ae_bool ae_fp_less(double v1, double v2)
Definition: ap.cpp:1327
void kdtreequeryresultsxy(kdtree *kdt, ae_matrix *xy, ae_state *_state)
void ae_serializer_unserialize_int(ae_serializer *serializer, ae_int_t *v, ae_state *state)
Definition: ap.cpp:3589
ae_int_t kdtreequeryrnn(const kdtree &kdt, const real_1d_array &x, const double r, const bool selfmatch)
Definition: alglibmisc.cpp:856
ae_int_t debugcounter
Definition: alglibmisc.h:61
#define ae_bool
Definition: ap.h:194
void tagheappushi(ae_vector *a, ae_vector *b, ae_int_t *n, double va, ae_int_t vb, ae_state *_state)
ae_bool ae_fp_neq(double v1, double v2)
Definition: ap.cpp:1321
ae_bool isfinitevector(ae_vector *x, ae_int_t n, ae_state *_state)
void allocrealmatrix(ae_serializer *s, ae_matrix *v, ae_int_t n0, ae_int_t n1, ae_state *_state)
ae_bool _hqrndstate_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void ae_touch_ptr(void *p)
Definition: ap.cpp:294
void kdtreequeryresultstagsi(kdtree *kdt, ae_vector *tags, ae_state *_state)
double ae_maxreal(double m1, double m2, ae_state *state)
Definition: ap.cpp:1577
ae_error_type
Definition: ap.h:201
void _kdtree_clear(void *_p)
ae_bool ae_vector_set_length(ae_vector *dst, ae_int_t newsize, ae_state *state)
Definition: ap.cpp:658
virtual ~kdtree()
Definition: alglibmisc.cpp:442
void unserializeintegerarray(ae_serializer *s, ae_vector *v, ae_state *_state)
void hqrndrandomize(hqrndstate *state, ae_state *_state)
void kdtreeunserialize(ae_serializer *s, kdtree *tree, ae_state *_state)
double ae_log(double x, ae_state *state)
Definition: ap.cpp:1679
ae_bool _hqrndstate_init(void *_p, ae_state *_state, ae_bool make_automatic)
struct alglib_impl::ae_vector ae_vector
const alglib_impl::ae_vector * c_ptr() const
Definition: ap.cpp:5907
#define j
double ae_minreal(double m1, double m2, ae_state *state)
Definition: ap.cpp:1582
hqrndstate & operator=(const hqrndstate &rhs)
Definition: alglibmisc.cpp:101
double ** pp_double
Definition: ap.h:455
void _kdtree_destroy(void *_p)
void ae_state_init(ae_state *state)
Definition: ap.cpp:309
double ae_sqrt(double x, ae_state *state)
Definition: ap.cpp:1535
void ae_assert(ae_bool cond, const char *msg, ae_state *state)
Definition: ap.cpp:1227
union alglib_impl::ae_vector::@11 ptr
ae_int_t rows() const
Definition: ap.cpp:6419
double hqrndnormal(const hqrndstate &state)
Definition: alglibmisc.cpp:222
void ae_serializer_alloc_start(ae_serializer *serializer)
Definition: ap.cpp:3404
const char *volatile error_msg
Definition: ap.h:389
void hqrndunit2(hqrndstate *state, double *x, double *y, ae_state *_state)
void kdtreequeryresultsx(kdtree *kdt, ae_matrix *x, ae_state *_state)
void serializerealmatrix(ae_serializer *s, ae_matrix *v, ae_int_t n0, ae_int_t n1, ae_state *_state)
double hqrndnormal(hqrndstate *state, ae_state *_state)
void kdtreequeryresultsxy(const kdtree &kdt, real_2d_array &xy)
ae_vector curboxmax
Definition: alglibmisc.h:59
ptrdiff_t ae_int_t
Definition: ap.h:186
doublereal * u
ae_bool ae_vector_init(ae_vector *dst, ae_int_t size, ae_datatype datatype, ae_state *state, ae_bool make_automatic)
Definition: ap.cpp:580
ae_int_t ae_maxint(ae_int_t m1, ae_int_t m2, ae_state *state)
Definition: ap.cpp:1567
double ae_sqr(double x, ae_state *state)
Definition: ap.cpp:1530
void(* obj)()
void ae_serializer_alloc_entry(ae_serializer *serializer)
Definition: ap.cpp:3411
void hqrndrandomize(hqrndstate &state)
Definition: alglibmisc.cpp:120
ae_int_t * p_int
Definition: ap.h:436
_hqrndstate_owner & operator=(const _hqrndstate_owner &rhs)
Definition: alglibmisc.cpp:68
ae_bool ae_vector_init_copy(ae_vector *dst, ae_vector *src, ae_state *state, ae_bool make_automatic)
Definition: ap.cpp:614
void kdtreeserialize(kdtree &obj, std::string &s_out)
Definition: alglibmisc.cpp:467
ae_bool ae_fp_less_eq(double v1, double v2)
Definition: ap.cpp:1335
double v0
alglib_impl::ae_int_t ae_int_t
Definition: ap.h:889
double hqrndcontinuous(const hqrndstate &state, const real_1d_array &x, const ae_int_t n)
Definition: alglibmisc.cpp:364
void ae_frame_leave(ae_state *state)
Definition: ap.cpp:415
void ae_matrix_clear(ae_matrix *dst)
Definition: ap.cpp:891
#define ae_true
Definition: ap.h:195
int * n
ae_bool ae_fp_greater(double v1, double v2)
Definition: ap.cpp:1343
ae_int_t cnt
Definition: ap.h:429
ae_bool ae_matrix_set_length(ae_matrix *dst, ae_int_t rows, ae_int_t cols, ae_state *state)
Definition: ap.cpp:854
doublereal * a
void tagheapreplacetopi(ae_vector *a, ae_vector *b, ae_int_t n, double va, ae_int_t vb, ae_state *_state)
void kdtreebuild(ae_matrix *xy, ae_int_t n, ae_int_t nx, ae_int_t ny, ae_int_t normtype, kdtree *kdt, ae_state *_state)
void tagheappopi(ae_vector *a, ae_vector *b, ae_int_t *n, ae_state *_state)
void hqrndunit2(const hqrndstate &state, double &x, double &y)
Definition: alglibmisc.cpp:246
ae_int_t ae_minint(ae_int_t m1, ae_int_t m2, ae_state *state)
Definition: ap.cpp:1572
_kdtree_owner & operator=(const _kdtree_owner &rhs)
Definition: alglibmisc.cpp:401
void kdtreebuildtagged(ae_matrix *xy, ae_vector *tags, ae_int_t n, ae_int_t nx, ae_int_t ny, ae_int_t normtype, kdtree *kdt, ae_state *_state)
void ae_free(void *p)
Definition: ap.cpp:237
void _hqrndstate_destroy(void *_p)