/************************************************************************* ALGLIB 3.16.0 (source code generated 2019-12-19) Copyright (c) Sergey Bochkanov (ALGLIB project). >>> SOURCE LICENSE >>> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation (www.fsf.org); either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. A copy of the GNU General Public License is available at http://www.fsf.org/licensing/licenses >>> END OF LICENSE >>> *************************************************************************/ #ifdef _MSC_VER #define _CRT_SECURE_NO_WARNINGS #endif #include "stdafx.h" #include "alglibmisc.h" // disable some irrelevant warnings #if (AE_COMPILER==AE_MSVC) && !defined(AE_ALL_WARNINGS) #pragma warning(disable:4100) #pragma warning(disable:4127) #pragma warning(disable:4611) #pragma warning(disable:4702) #pragma warning(disable:4996) #endif ///////////////////////////////////////////////////////////////////////// // // THIS SECTION CONTAINS IMPLEMENTATION OF C++ INTERFACE // ///////////////////////////////////////////////////////////////////////// namespace alglib { #if defined(AE_COMPILE_NEARESTNEIGHBOR) || !defined(AE_PARTIAL_BUILD) #endif #if defined(AE_COMPILE_HQRND) || !defined(AE_PARTIAL_BUILD) #endif #if defined(AE_COMPILE_XDEBUG) || !defined(AE_PARTIAL_BUILD) #endif #if defined(AE_COMPILE_NEARESTNEIGHBOR) || !defined(AE_PARTIAL_BUILD) /************************************************************************* Buffer object which is used to perform nearest neighbor requests in the multithreaded mode (multiple threads working with same KD-tree object). This object should be created with KDTreeCreateRequestBuffer(). *************************************************************************/ _kdtreerequestbuffer_owner::_kdtreerequestbuffer_owner() { jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { if( p_struct!=NULL ) { alglib_impl::_kdtreerequestbuffer_destroy(p_struct); alglib_impl::ae_free(p_struct); } p_struct = NULL; #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); p_struct = NULL; p_struct = (alglib_impl::kdtreerequestbuffer*)alglib_impl::ae_malloc(sizeof(alglib_impl::kdtreerequestbuffer), &_state); memset(p_struct, 0, sizeof(alglib_impl::kdtreerequestbuffer)); alglib_impl::_kdtreerequestbuffer_init(p_struct, &_state, ae_false); ae_state_clear(&_state); } _kdtreerequestbuffer_owner::_kdtreerequestbuffer_owner(const _kdtreerequestbuffer_owner &rhs) { jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { if( p_struct!=NULL ) { alglib_impl::_kdtreerequestbuffer_destroy(p_struct); alglib_impl::ae_free(p_struct); } p_struct = NULL; #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); p_struct = NULL; alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: kdtreerequestbuffer copy constructor failure (source is not initialized)", &_state); p_struct = (alglib_impl::kdtreerequestbuffer*)alglib_impl::ae_malloc(sizeof(alglib_impl::kdtreerequestbuffer), &_state); memset(p_struct, 0, sizeof(alglib_impl::kdtreerequestbuffer)); alglib_impl::_kdtreerequestbuffer_init_copy(p_struct, const_cast(rhs.p_struct), &_state, ae_false); ae_state_clear(&_state); } _kdtreerequestbuffer_owner& _kdtreerequestbuffer_owner::operator=(const _kdtreerequestbuffer_owner &rhs) { if( this==&rhs ) return *this; jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return *this; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: kdtreerequestbuffer assignment constructor failure (destination is not initialized)", &_state); alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: kdtreerequestbuffer assignment constructor failure (source is not initialized)", &_state); alglib_impl::_kdtreerequestbuffer_destroy(p_struct); memset(p_struct, 0, sizeof(alglib_impl::kdtreerequestbuffer)); alglib_impl::_kdtreerequestbuffer_init_copy(p_struct, const_cast(rhs.p_struct), &_state, ae_false); ae_state_clear(&_state); return *this; } _kdtreerequestbuffer_owner::~_kdtreerequestbuffer_owner() { if( p_struct!=NULL ) { alglib_impl::_kdtreerequestbuffer_destroy(p_struct); ae_free(p_struct); } } alglib_impl::kdtreerequestbuffer* _kdtreerequestbuffer_owner::c_ptr() { return p_struct; } alglib_impl::kdtreerequestbuffer* _kdtreerequestbuffer_owner::c_ptr() const { return const_cast(p_struct); } kdtreerequestbuffer::kdtreerequestbuffer() : _kdtreerequestbuffer_owner() { } kdtreerequestbuffer::kdtreerequestbuffer(const kdtreerequestbuffer &rhs):_kdtreerequestbuffer_owner(rhs) { } kdtreerequestbuffer& kdtreerequestbuffer::operator=(const kdtreerequestbuffer &rhs) { if( this==&rhs ) return *this; _kdtreerequestbuffer_owner::operator=(rhs); return *this; } kdtreerequestbuffer::~kdtreerequestbuffer() { } /************************************************************************* KD-tree object. *************************************************************************/ _kdtree_owner::_kdtree_owner() { jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { if( p_struct!=NULL ) { alglib_impl::_kdtree_destroy(p_struct); alglib_impl::ae_free(p_struct); } p_struct = NULL; #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); p_struct = NULL; p_struct = (alglib_impl::kdtree*)alglib_impl::ae_malloc(sizeof(alglib_impl::kdtree), &_state); memset(p_struct, 0, sizeof(alglib_impl::kdtree)); alglib_impl::_kdtree_init(p_struct, &_state, ae_false); ae_state_clear(&_state); } _kdtree_owner::_kdtree_owner(const _kdtree_owner &rhs) { jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { if( p_struct!=NULL ) { alglib_impl::_kdtree_destroy(p_struct); alglib_impl::ae_free(p_struct); } p_struct = NULL; #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); p_struct = NULL; alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: kdtree copy constructor failure (source is not initialized)", &_state); p_struct = (alglib_impl::kdtree*)alglib_impl::ae_malloc(sizeof(alglib_impl::kdtree), &_state); memset(p_struct, 0, sizeof(alglib_impl::kdtree)); alglib_impl::_kdtree_init_copy(p_struct, const_cast(rhs.p_struct), &_state, ae_false); ae_state_clear(&_state); } _kdtree_owner& _kdtree_owner::operator=(const _kdtree_owner &rhs) { if( this==&rhs ) return *this; jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return *this; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: kdtree assignment constructor failure (destination is not initialized)", &_state); alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: kdtree assignment constructor failure (source is not initialized)", &_state); alglib_impl::_kdtree_destroy(p_struct); memset(p_struct, 0, sizeof(alglib_impl::kdtree)); alglib_impl::_kdtree_init_copy(p_struct, const_cast(rhs.p_struct), &_state, ae_false); ae_state_clear(&_state); return *this; } _kdtree_owner::~_kdtree_owner() { if( p_struct!=NULL ) { alglib_impl::_kdtree_destroy(p_struct); ae_free(p_struct); } } alglib_impl::kdtree* _kdtree_owner::c_ptr() { return p_struct; } alglib_impl::kdtree* _kdtree_owner::c_ptr() const { return const_cast(p_struct); } kdtree::kdtree() : _kdtree_owner() { } kdtree::kdtree(const kdtree &rhs):_kdtree_owner(rhs) { } kdtree& kdtree::operator=(const kdtree &rhs) { if( this==&rhs ) return *this; _kdtree_owner::operator=(rhs); return *this; } kdtree::~kdtree() { } /************************************************************************* This function serializes data structure to string. Important properties of s_out: * it contains alphanumeric characters, dots, underscores, minus signs * these symbols are grouped into words, which are separated by spaces and Windows-style (CR+LF) newlines * although serializer uses spaces and CR+LF as separators, you can replace any separator character by arbitrary combination of spaces, tabs, Windows or Unix newlines. It allows flexible reformatting of the string in case you want to include it into text or XML file. But you should not insert separators into the middle of the "words" nor you should change case of letters. * s_out can be freely moved between 32-bit and 64-bit systems, little and big endian machines, and so on. You can serialize structure on 32-bit machine and unserialize it on 64-bit one (or vice versa), or serialize it on SPARC and unserialize on x86. You can also serialize it in C++ version of ALGLIB and unserialize in C# one, and vice versa. *************************************************************************/ void kdtreeserialize(kdtree &obj, std::string &s_out) { jmp_buf _break_jump; alglib_impl::ae_state state; alglib_impl::ae_serializer serializer; alglib_impl::ae_int_t ssize; alglib_impl::ae_state_init(&state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(state.error_msg); return; #endif } ae_state_set_break_jump(&state, &_break_jump); alglib_impl::ae_serializer_init(&serializer); alglib_impl::ae_serializer_alloc_start(&serializer); alglib_impl::kdtreealloc(&serializer, obj.c_ptr(), &state); ssize = alglib_impl::ae_serializer_get_alloc_size(&serializer); s_out.clear(); s_out.reserve((size_t)(ssize+1)); alglib_impl::ae_serializer_sstart_str(&serializer, &s_out); alglib_impl::kdtreeserialize(&serializer, obj.c_ptr(), &state); alglib_impl::ae_serializer_stop(&serializer, &state); alglib_impl::ae_assert( s_out.length()<=(size_t)ssize, "ALGLIB: serialization integrity error", &state); alglib_impl::ae_serializer_clear(&serializer); alglib_impl::ae_state_clear(&state); } /************************************************************************* This function unserializes data structure from string. *************************************************************************/ void kdtreeunserialize(const std::string &s_in, kdtree &obj) { jmp_buf _break_jump; alglib_impl::ae_state state; alglib_impl::ae_serializer serializer; alglib_impl::ae_state_init(&state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(state.error_msg); return; #endif } ae_state_set_break_jump(&state, &_break_jump); alglib_impl::ae_serializer_init(&serializer); alglib_impl::ae_serializer_ustart_str(&serializer, &s_in); alglib_impl::kdtreeunserialize(&serializer, obj.c_ptr(), &state); alglib_impl::ae_serializer_stop(&serializer, &state); alglib_impl::ae_serializer_clear(&serializer); alglib_impl::ae_state_clear(&state); } /************************************************************************* This function serializes data structure to C++ stream. Data stream generated by this function is same as string representation generated by string version of serializer - alphanumeric characters, dots, underscores, minus signs, which are grouped into words separated by spaces and CR+LF. We recommend you to read comments on string version of serializer to find out more about serialization of AlGLIB objects. *************************************************************************/ void kdtreeserialize(kdtree &obj, std::ostream &s_out) { jmp_buf _break_jump; alglib_impl::ae_state state; alglib_impl::ae_serializer serializer; alglib_impl::ae_state_init(&state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(state.error_msg); return; #endif } ae_state_set_break_jump(&state, &_break_jump); alglib_impl::ae_serializer_init(&serializer); alglib_impl::ae_serializer_alloc_start(&serializer); alglib_impl::kdtreealloc(&serializer, obj.c_ptr(), &state); alglib_impl::ae_serializer_get_alloc_size(&serializer); // not actually needed, but we have to ask alglib_impl::ae_serializer_sstart_stream(&serializer, &s_out); alglib_impl::kdtreeserialize(&serializer, obj.c_ptr(), &state); alglib_impl::ae_serializer_stop(&serializer, &state); alglib_impl::ae_serializer_clear(&serializer); alglib_impl::ae_state_clear(&state); } /************************************************************************* This function unserializes data structure from stream. *************************************************************************/ void kdtreeunserialize(const std::istream &s_in, kdtree &obj) { jmp_buf _break_jump; alglib_impl::ae_state state; alglib_impl::ae_serializer serializer; alglib_impl::ae_state_init(&state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(state.error_msg); return; #endif } ae_state_set_break_jump(&state, &_break_jump); alglib_impl::ae_serializer_init(&serializer); alglib_impl::ae_serializer_ustart_stream(&serializer, &s_in); alglib_impl::kdtreeunserialize(&serializer, obj.c_ptr(), &state); alglib_impl::ae_serializer_stop(&serializer, &state); alglib_impl::ae_serializer_clear(&serializer); alglib_impl::ae_state_clear(&state); } /************************************************************************* KD-tree creation This subroutine creates KD-tree from set of X-values and optional Y-values INPUT PARAMETERS XY - dataset, array[0..N-1,0..NX+NY-1]. one row corresponds to one point. first NX columns contain X-values, next NY (NY may be zero) columns may contain associated Y-values N - number of points, N>=0. NX - space dimension, NX>=1. NY - number of optional Y-values, NY>=0. NormType- norm type: * 0 denotes infinity-norm * 1 denotes 1-norm * 2 denotes 2-norm (Euclidean norm) OUTPUT PARAMETERS KDT - KD-tree NOTES 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory requirements. 2. Although KD-trees may be used with any combination of N and NX, they are more efficient than brute-force search only when N >> 4^NX. So they are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another inefficient case, because simple binary search (without additional structures) is much more efficient in such tasks than KD-trees. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ 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, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreebuild(const_cast(xy.c_ptr()), n, nx, ny, normtype, const_cast(kdt.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* KD-tree creation This subroutine creates KD-tree from set of X-values and optional Y-values INPUT PARAMETERS XY - dataset, array[0..N-1,0..NX+NY-1]. one row corresponds to one point. first NX columns contain X-values, next NY (NY may be zero) columns may contain associated Y-values N - number of points, N>=0. NX - space dimension, NX>=1. NY - number of optional Y-values, NY>=0. NormType- norm type: * 0 denotes infinity-norm * 1 denotes 1-norm * 2 denotes 2-norm (Euclidean norm) OUTPUT PARAMETERS KDT - KD-tree NOTES 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory requirements. 2. Although KD-trees may be used with any combination of N and NX, they are more efficient than brute-force search only when N >> 4^NX. So they are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another inefficient case, because simple binary search (without additional structures) is much more efficient in such tasks than KD-trees. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ #if !defined(AE_NO_EXCEPTIONS) void kdtreebuild(const real_2d_array &xy, const ae_int_t nx, const ae_int_t ny, const ae_int_t normtype, kdtree &kdt, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; ae_int_t n; n = xy.rows(); alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreebuild(const_cast(xy.c_ptr()), n, nx, ny, normtype, const_cast(kdt.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } #endif /************************************************************************* KD-tree creation This subroutine creates KD-tree from set of X-values, integer tags and optional Y-values INPUT PARAMETERS XY - dataset, array[0..N-1,0..NX+NY-1]. one row corresponds to one point. first NX columns contain X-values, next NY (NY may be zero) columns may contain associated Y-values Tags - tags, array[0..N-1], contains integer tags associated with points. N - number of points, N>=0 NX - space dimension, NX>=1. NY - number of optional Y-values, NY>=0. NormType- norm type: * 0 denotes infinity-norm * 1 denotes 1-norm * 2 denotes 2-norm (Euclidean norm) OUTPUT PARAMETERS KDT - KD-tree NOTES 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory requirements. 2. Although KD-trees may be used with any combination of N and NX, they are more efficient than brute-force search only when N >> 4^NX. So they are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another inefficient case, because simple binary search (without additional structures) is much more efficient in such tasks than KD-trees. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ 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, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreebuildtagged(const_cast(xy.c_ptr()), const_cast(tags.c_ptr()), n, nx, ny, normtype, const_cast(kdt.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* KD-tree creation This subroutine creates KD-tree from set of X-values, integer tags and optional Y-values INPUT PARAMETERS XY - dataset, array[0..N-1,0..NX+NY-1]. one row corresponds to one point. first NX columns contain X-values, next NY (NY may be zero) columns may contain associated Y-values Tags - tags, array[0..N-1], contains integer tags associated with points. N - number of points, N>=0 NX - space dimension, NX>=1. NY - number of optional Y-values, NY>=0. NormType- norm type: * 0 denotes infinity-norm * 1 denotes 1-norm * 2 denotes 2-norm (Euclidean norm) OUTPUT PARAMETERS KDT - KD-tree NOTES 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory requirements. 2. Although KD-trees may be used with any combination of N and NX, they are more efficient than brute-force search only when N >> 4^NX. So they are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another inefficient case, because simple binary search (without additional structures) is much more efficient in such tasks than KD-trees. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ #if !defined(AE_NO_EXCEPTIONS) 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, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; ae_int_t n; if( (xy.rows()!=tags.length())) _ALGLIB_CPP_EXCEPTION("Error while calling 'kdtreebuildtagged': looks like one of arguments has wrong size"); n = xy.rows(); alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreebuildtagged(const_cast(xy.c_ptr()), const_cast(tags.c_ptr()), n, nx, ny, normtype, const_cast(kdt.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } #endif /************************************************************************* This function creates buffer structure which can be used to perform parallel KD-tree requests. KD-tree subpackage provides two sets of request functions - ones which use internal buffer of KD-tree object (these functions are single-threaded because they use same buffer, which can not shared between threads), and ones which use external buffer. This function is used to initialize external buffer. INPUT PARAMETERS KDT - KD-tree which is associated with newly created buffer OUTPUT PARAMETERS Buf - external buffer. IMPORTANT: KD-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use buffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ void kdtreecreaterequestbuffer(const kdtree &kdt, kdtreerequestbuffer &buf, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreecreaterequestbuffer(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* K-NN query: K nearest neighbors IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: KDTreeTsQueryKNN() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of actual neighbors found (either K or N, if K>N). This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain these results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreequeryknn(const kdtree &kdt, const real_1d_array &x, const ae_int_t k, const bool selfmatch, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreequeryknn(const_cast(kdt.c_ptr()), const_cast(x.c_ptr()), k, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* K-NN query: K nearest neighbors IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: KDTreeTsQueryKNN() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of actual neighbors found (either K or N, if K>N). This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain these results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ #if !defined(AE_NO_EXCEPTIONS) ae_int_t kdtreequeryknn(const kdtree &kdt, const real_1d_array &x, const ae_int_t k, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; bool selfmatch; selfmatch = true; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreequeryknn(const_cast(kdt.c_ptr()), const_cast(x.c_ptr()), k, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } #endif /************************************************************************* K-NN query: K nearest neighbors, using external thread-local buffer. You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - kd-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of actual neighbors found (either K or N, if K>N). This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreetsqueryknn(const kdtree &kdt, const kdtreerequestbuffer &buf, const real_1d_array &x, const ae_int_t k, const bool selfmatch, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreetsqueryknn(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(x.c_ptr()), k, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* K-NN query: K nearest neighbors, using external thread-local buffer. You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - kd-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of actual neighbors found (either K or N, if K>N). This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ #if !defined(AE_NO_EXCEPTIONS) ae_int_t kdtreetsqueryknn(const kdtree &kdt, const kdtreerequestbuffer &buf, const real_1d_array &x, const ae_int_t k, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; bool selfmatch; selfmatch = true; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreetsqueryknn(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(x.c_ptr()), k, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } #endif /************************************************************************* R-NN query: all points within R-sphere centered at X, ordered by distance between point and X (by ascending). NOTE: it is also possible to perform undordered queries performed by means of kdtreequeryrnnu() and kdtreetsqueryrnnu() functions. Such queries are faster because we do not have to use heap structure for sorting. IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: kdtreetsqueryrnn() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain actual results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreequeryrnn(const kdtree &kdt, const real_1d_array &x, const double r, const bool selfmatch, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreequeryrnn(const_cast(kdt.c_ptr()), const_cast(x.c_ptr()), r, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* R-NN query: all points within R-sphere centered at X, ordered by distance between point and X (by ascending). NOTE: it is also possible to perform undordered queries performed by means of kdtreequeryrnnu() and kdtreetsqueryrnnu() functions. Such queries are faster because we do not have to use heap structure for sorting. IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: kdtreetsqueryrnn() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain actual results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ #if !defined(AE_NO_EXCEPTIONS) ae_int_t kdtreequeryrnn(const kdtree &kdt, const real_1d_array &x, const double r, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; bool selfmatch; selfmatch = true; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreequeryrnn(const_cast(kdt.c_ptr()), const_cast(x.c_ptr()), r, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } #endif /************************************************************************* R-NN query: all points within R-sphere centered at X, no ordering by distance as undicated by "U" suffix (faster that ordered query, for large queries - significantly faster). IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: kdtreetsqueryrnn() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain actual results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances As indicated by "U" suffix, this function returns unordered results. -- ALGLIB -- Copyright 01.11.2018 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreequeryrnnu(const kdtree &kdt, const real_1d_array &x, const double r, const bool selfmatch, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreequeryrnnu(const_cast(kdt.c_ptr()), const_cast(x.c_ptr()), r, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* R-NN query: all points within R-sphere centered at X, no ordering by distance as undicated by "U" suffix (faster that ordered query, for large queries - significantly faster). IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: kdtreetsqueryrnn() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain actual results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances As indicated by "U" suffix, this function returns unordered results. -- ALGLIB -- Copyright 01.11.2018 by Bochkanov Sergey *************************************************************************/ #if !defined(AE_NO_EXCEPTIONS) ae_int_t kdtreequeryrnnu(const kdtree &kdt, const real_1d_array &x, const double r, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; bool selfmatch; selfmatch = true; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreequeryrnnu(const_cast(kdt.c_ptr()), const_cast(x.c_ptr()), r, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } #endif /************************************************************************* R-NN query: all points within R-sphere centered at X, using external thread-local buffer, sorted by distance between point and X (by ascending) You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. NOTE: it is also possible to perform undordered queries performed by means of kdtreequeryrnnu() and kdtreetsqueryrnnu() functions. Such queries are faster because we do not have to use heap structure for sorting. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreetsqueryrnn(const kdtree &kdt, const kdtreerequestbuffer &buf, const real_1d_array &x, const double r, const bool selfmatch, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreetsqueryrnn(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(x.c_ptr()), r, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* R-NN query: all points within R-sphere centered at X, using external thread-local buffer, sorted by distance between point and X (by ascending) You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. NOTE: it is also possible to perform undordered queries performed by means of kdtreequeryrnnu() and kdtreetsqueryrnnu() functions. Such queries are faster because we do not have to use heap structure for sorting. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ #if !defined(AE_NO_EXCEPTIONS) ae_int_t kdtreetsqueryrnn(const kdtree &kdt, const kdtreerequestbuffer &buf, const real_1d_array &x, const double r, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; bool selfmatch; selfmatch = true; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreetsqueryrnn(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(x.c_ptr()), r, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } #endif /************************************************************************* R-NN query: all points within R-sphere centered at X, using external thread-local buffer, no ordering by distance as undicated by "U" suffix (faster that ordered query, for large queries - significantly faster). You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances As indicated by "U" suffix, this function returns unordered results. IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreetsqueryrnnu(const kdtree &kdt, const kdtreerequestbuffer &buf, const real_1d_array &x, const double r, const bool selfmatch, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreetsqueryrnnu(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(x.c_ptr()), r, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* R-NN query: all points within R-sphere centered at X, using external thread-local buffer, no ordering by distance as undicated by "U" suffix (faster that ordered query, for large queries - significantly faster). You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances As indicated by "U" suffix, this function returns unordered results. IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ #if !defined(AE_NO_EXCEPTIONS) ae_int_t kdtreetsqueryrnnu(const kdtree &kdt, const kdtreerequestbuffer &buf, const real_1d_array &x, const double r, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; bool selfmatch; selfmatch = true; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreetsqueryrnnu(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(x.c_ptr()), r, selfmatch, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } #endif /************************************************************************* K-NN query: approximate K nearest neighbors IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: KDTreeTsQueryAKNN() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True Eps - approximation factor, Eps>=0. eps-approximate nearest neighbor is a neighbor whose distance from X is at most (1+eps) times distance of true nearest neighbor. RESULT number of actual neighbors found (either K or N, if K>N). NOTES significant performance gain may be achieved only when Eps is is on the order of magnitude of 1 or larger. This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain these results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreequeryaknn(const kdtree &kdt, const real_1d_array &x, const ae_int_t k, const bool selfmatch, const double eps, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreequeryaknn(const_cast(kdt.c_ptr()), const_cast(x.c_ptr()), k, selfmatch, eps, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* K-NN query: approximate K nearest neighbors IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: KDTreeTsQueryAKNN() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True Eps - approximation factor, Eps>=0. eps-approximate nearest neighbor is a neighbor whose distance from X is at most (1+eps) times distance of true nearest neighbor. RESULT number of actual neighbors found (either K or N, if K>N). NOTES significant performance gain may be achieved only when Eps is is on the order of magnitude of 1 or larger. This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain these results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ #if !defined(AE_NO_EXCEPTIONS) ae_int_t kdtreequeryaknn(const kdtree &kdt, const real_1d_array &x, const ae_int_t k, const double eps, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; bool selfmatch; selfmatch = true; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreequeryaknn(const_cast(kdt.c_ptr()), const_cast(x.c_ptr()), k, selfmatch, eps, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } #endif /************************************************************************* K-NN query: approximate K nearest neighbors, using thread-local buffer. You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True Eps - approximation factor, Eps>=0. eps-approximate nearest neighbor is a neighbor whose distance from X is at most (1+eps) times distance of true nearest neighbor. RESULT number of actual neighbors found (either K or N, if K>N). NOTES significant performance gain may be achieved only when Eps is is on the order of magnitude of 1 or larger. This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreetsqueryaknn(const kdtree &kdt, const kdtreerequestbuffer &buf, const real_1d_array &x, const ae_int_t k, const bool selfmatch, const double eps, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreetsqueryaknn(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(x.c_ptr()), k, selfmatch, eps, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* K-NN query: approximate K nearest neighbors, using thread-local buffer. You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True Eps - approximation factor, Eps>=0. eps-approximate nearest neighbor is a neighbor whose distance from X is at most (1+eps) times distance of true nearest neighbor. RESULT number of actual neighbors found (either K or N, if K>N). NOTES significant performance gain may be achieved only when Eps is is on the order of magnitude of 1 or larger. This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ #if !defined(AE_NO_EXCEPTIONS) ae_int_t kdtreetsqueryaknn(const kdtree &kdt, const kdtreerequestbuffer &buf, const real_1d_array &x, const ae_int_t k, const double eps, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; bool selfmatch; selfmatch = true; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreetsqueryaknn(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(x.c_ptr()), k, selfmatch, eps, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } #endif /************************************************************************* Box query: all points within user-specified box. IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: KDTreeTsQueryBox() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree BoxMin - lower bounds, array[0..NX-1]. BoxMax - upper bounds, array[0..NX-1]. RESULT number of actual neighbors found (in [0,N]). This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain these results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() returns zeros for this request NOTE: this particular query returns unordered results, because there is no meaningful way of ordering points. Furthermore, no 'distance' is associated with points - it is either INSIDE or OUTSIDE (so request for distances will return zeros). -- ALGLIB -- Copyright 14.05.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreequerybox(const kdtree &kdt, const real_1d_array &boxmin, const real_1d_array &boxmax, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreequerybox(const_cast(kdt.c_ptr()), const_cast(boxmin.c_ptr()), const_cast(boxmax.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* Box query: all points within user-specified box, using thread-local buffer. You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. BoxMin - lower bounds, array[0..NX-1]. BoxMax - upper bounds, array[0..NX-1]. RESULT number of actual neighbors found (in [0,N]). This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "ts" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() returns zeros for this query NOTE: this particular query returns unordered results, because there is no meaningful way of ordering points. Furthermore, no 'distance' is associated with points - it is either INSIDE or OUTSIDE (so request for distances will return zeros). IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 14.05.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreetsquerybox(const kdtree &kdt, const kdtreerequestbuffer &buf, const real_1d_array &boxmin, const real_1d_array &boxmax, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::kdtreetsquerybox(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(boxmin.c_ptr()), const_cast(boxmax.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* X-values from last query. This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - kdtreetsqueryresultsx(). INPUT PARAMETERS KDT - KD-tree X - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS X - rows are filled with X-values NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsTags() tag values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsx(const kdtree &kdt, real_2d_array &x, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreequeryresultsx(const_cast(kdt.c_ptr()), const_cast(x.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* X- and Y-values from last query This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - kdtreetsqueryresultsxy(). INPUT PARAMETERS KDT - KD-tree XY - possibly pre-allocated buffer. If XY is too small to store result, it is resized. If size(XY) is enough to store result, it is left unchanged. OUTPUT PARAMETERS XY - rows are filled with points: first NX columns with X-values, next NY columns - with Y-values. NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsTags() tag values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsxy(const kdtree &kdt, real_2d_array &xy, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreequeryresultsxy(const_cast(kdt.c_ptr()), const_cast(xy.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* Tags from last query This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - kdtreetsqueryresultstags(). INPUT PARAMETERS KDT - KD-tree Tags - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS Tags - filled with tags associated with points, or, when no tags were supplied, with zeros NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultstags(const kdtree &kdt, integer_1d_array &tags, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreequeryresultstags(const_cast(kdt.c_ptr()), const_cast(tags.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* Distances from last query This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - kdtreetsqueryresultsdistances(). INPUT PARAMETERS KDT - KD-tree R - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS R - filled with distances (in corresponding norm) NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsTags() tag values -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsdistances(const kdtree &kdt, real_1d_array &r, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreequeryresultsdistances(const_cast(kdt.c_ptr()), const_cast(r.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* X-values from last query associated with kdtreerequestbuffer object. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure. X - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS X - rows are filled with X-values NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsTags() tag values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreetsqueryresultsx(const kdtree &kdt, const kdtreerequestbuffer &buf, real_2d_array &x, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreetsqueryresultsx(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(x.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* X- and Y-values from last query associated with kdtreerequestbuffer object. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure. XY - possibly pre-allocated buffer. If XY is too small to store result, it is resized. If size(XY) is enough to store result, it is left unchanged. OUTPUT PARAMETERS XY - rows are filled with points: first NX columns with X-values, next NY columns - with Y-values. NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsTags() tag values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreetsqueryresultsxy(const kdtree &kdt, const kdtreerequestbuffer &buf, real_2d_array &xy, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreetsqueryresultsxy(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(xy.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* Tags from last query associated with kdtreerequestbuffer object. This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - KDTreeTsqueryresultstags(). INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure. Tags - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS Tags - filled with tags associated with points, or, when no tags were supplied, with zeros NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreetsqueryresultstags(const kdtree &kdt, const kdtreerequestbuffer &buf, integer_1d_array &tags, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreetsqueryresultstags(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(tags.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* Distances from last query associated with kdtreerequestbuffer object. This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - KDTreeTsqueryresultsdistances(). INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure. R - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS R - filled with distances (in corresponding norm) NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsTags() tag values -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreetsqueryresultsdistances(const kdtree &kdt, const kdtreerequestbuffer &buf, real_1d_array &r, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreetsqueryresultsdistances(const_cast(kdt.c_ptr()), const_cast(buf.c_ptr()), const_cast(r.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* X-values from last query; 'interactive' variant for languages like Python which support constructs like "X = KDTreeQueryResultsXI(KDT)" and interactive mode of interpreter. This function allocates new array on each call, so it is significantly slower than its 'non-interactive' counterpart, but it is more convenient when you call it from command line. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsxi(const kdtree &kdt, real_2d_array &x, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreequeryresultsxi(const_cast(kdt.c_ptr()), const_cast(x.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* XY-values from last query; 'interactive' variant for languages like Python which support constructs like "XY = KDTreeQueryResultsXYI(KDT)" and interactive mode of interpreter. This function allocates new array on each call, so it is significantly slower than its 'non-interactive' counterpart, but it is more convenient when you call it from command line. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsxyi(const kdtree &kdt, real_2d_array &xy, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreequeryresultsxyi(const_cast(kdt.c_ptr()), const_cast(xy.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* Tags from last query; 'interactive' variant for languages like Python which support constructs like "Tags = KDTreeQueryResultsTagsI(KDT)" and interactive mode of interpreter. This function allocates new array on each call, so it is significantly slower than its 'non-interactive' counterpart, but it is more convenient when you call it from command line. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultstagsi(const kdtree &kdt, integer_1d_array &tags, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreequeryresultstagsi(const_cast(kdt.c_ptr()), const_cast(tags.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* Distances from last query; 'interactive' variant for languages like Python which support constructs like "R = KDTreeQueryResultsDistancesI(KDT)" and interactive mode of interpreter. This function allocates new array on each call, so it is significantly slower than its 'non-interactive' counterpart, but it is more convenient when you call it from command line. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsdistancesi(const kdtree &kdt, real_1d_array &r, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::kdtreequeryresultsdistancesi(const_cast(kdt.c_ptr()), const_cast(r.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } #endif #if defined(AE_COMPILE_HQRND) || !defined(AE_PARTIAL_BUILD) /************************************************************************* Portable high quality random number generator state. Initialized with HQRNDRandomize() or HQRNDSeed(). Fields: S1, S2 - seed values V - precomputed value MagicV - 'magic' value used to determine whether State structure was correctly initialized. *************************************************************************/ _hqrndstate_owner::_hqrndstate_owner() { jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { if( p_struct!=NULL ) { alglib_impl::_hqrndstate_destroy(p_struct); alglib_impl::ae_free(p_struct); } p_struct = NULL; #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); p_struct = NULL; p_struct = (alglib_impl::hqrndstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::hqrndstate), &_state); memset(p_struct, 0, sizeof(alglib_impl::hqrndstate)); alglib_impl::_hqrndstate_init(p_struct, &_state, ae_false); ae_state_clear(&_state); } _hqrndstate_owner::_hqrndstate_owner(const _hqrndstate_owner &rhs) { jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { if( p_struct!=NULL ) { alglib_impl::_hqrndstate_destroy(p_struct); alglib_impl::ae_free(p_struct); } p_struct = NULL; #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); p_struct = NULL; alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: hqrndstate copy constructor failure (source is not initialized)", &_state); p_struct = (alglib_impl::hqrndstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::hqrndstate), &_state); memset(p_struct, 0, sizeof(alglib_impl::hqrndstate)); alglib_impl::_hqrndstate_init_copy(p_struct, const_cast(rhs.p_struct), &_state, ae_false); ae_state_clear(&_state); } _hqrndstate_owner& _hqrndstate_owner::operator=(const _hqrndstate_owner &rhs) { if( this==&rhs ) return *this; jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return *this; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: hqrndstate assignment constructor failure (destination is not initialized)", &_state); alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: hqrndstate assignment constructor failure (source is not initialized)", &_state); alglib_impl::_hqrndstate_destroy(p_struct); memset(p_struct, 0, sizeof(alglib_impl::hqrndstate)); alglib_impl::_hqrndstate_init_copy(p_struct, const_cast(rhs.p_struct), &_state, ae_false); ae_state_clear(&_state); return *this; } _hqrndstate_owner::~_hqrndstate_owner() { if( p_struct!=NULL ) { alglib_impl::_hqrndstate_destroy(p_struct); ae_free(p_struct); } } alglib_impl::hqrndstate* _hqrndstate_owner::c_ptr() { return p_struct; } alglib_impl::hqrndstate* _hqrndstate_owner::c_ptr() const { return const_cast(p_struct); } hqrndstate::hqrndstate() : _hqrndstate_owner() { } hqrndstate::hqrndstate(const hqrndstate &rhs):_hqrndstate_owner(rhs) { } hqrndstate& hqrndstate::operator=(const hqrndstate &rhs) { if( this==&rhs ) return *this; _hqrndstate_owner::operator=(rhs); return *this; } hqrndstate::~hqrndstate() { } /************************************************************************* HQRNDState initialization with random values which come from standard RNG. -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ void hqrndrandomize(hqrndstate &state, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::hqrndrandomize(const_cast(state.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* HQRNDState initialization with seed values -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ void hqrndseed(const ae_int_t s1, const ae_int_t s2, hqrndstate &state, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::hqrndseed(s1, s2, const_cast(state.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This function generates random real number in (0,1), not including interval boundaries State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ double hqrnduniformr(const hqrndstate &state, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); double result = alglib_impl::hqrnduniformr(const_cast(state.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This function generates random integer number in [0, N) 1. State structure must be initialized with HQRNDRandomize() or HQRNDSeed() 2. N can be any positive number except for very large numbers: * close to 2^31 on 32-bit systems * close to 2^62 on 64-bit systems An exception will be generated if N is too large. -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ ae_int_t hqrnduniformi(const hqrndstate &state, const ae_int_t n, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::hqrnduniformi(const_cast(state.c_ptr()), n, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* Random number generator: normal numbers This function generates one random number from normal distribution. Its performance is equal to that of HQRNDNormal2() State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ double hqrndnormal(const hqrndstate &state, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); double result = alglib_impl::hqrndnormal(const_cast(state.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* Random number generator: random X and Y such that X^2+Y^2=1 State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ void hqrndunit2(const hqrndstate &state, double &x, double &y, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::hqrndunit2(const_cast(state.c_ptr()), &x, &y, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* Random number generator: normal numbers This function generates two independent random numbers from normal distribution. Its performance is equal to that of HQRNDNormal() State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ void hqrndnormal2(const hqrndstate &state, double &x1, double &x2, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::hqrndnormal2(const_cast(state.c_ptr()), &x1, &x2, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* Random number generator: exponential distribution State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 11.08.2007 by Bochkanov Sergey *************************************************************************/ double hqrndexponential(const hqrndstate &state, const double lambdav, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); double result = alglib_impl::hqrndexponential(const_cast(state.c_ptr()), lambdav, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This function generates random number from discrete distribution given by finite sample X. INPUT PARAMETERS State - high quality random number generator, must be initialized with HQRNDRandomize() or HQRNDSeed(). X - finite sample N - number of elements to use, N>=1 RESULT this function returns one of the X[i] for random i=0..N-1 -- ALGLIB -- Copyright 08.11.2011 by Bochkanov Sergey *************************************************************************/ double hqrnddiscrete(const hqrndstate &state, const real_1d_array &x, const ae_int_t n, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); double result = alglib_impl::hqrnddiscrete(const_cast(state.c_ptr()), const_cast(x.c_ptr()), n, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This function generates random number from continuous distribution given by finite sample X. INPUT PARAMETERS State - high quality random number generator, must be initialized with HQRNDRandomize() or HQRNDSeed(). X - finite sample, array[N] (can be larger, in this case only leading N elements are used). THIS ARRAY MUST BE SORTED BY ASCENDING. N - number of elements to use, N>=1 RESULT this function returns random number from continuous distribution which tries to approximate X as mush as possible. min(X)<=Result<=max(X). -- ALGLIB -- Copyright 08.11.2011 by Bochkanov Sergey *************************************************************************/ double hqrndcontinuous(const hqrndstate &state, const real_1d_array &x, const ae_int_t n, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); double result = alglib_impl::hqrndcontinuous(const_cast(state.c_ptr()), const_cast(x.c_ptr()), n, &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } #endif #if defined(AE_COMPILE_XDEBUG) || !defined(AE_PARTIAL_BUILD) /************************************************************************* *************************************************************************/ _xdebugrecord1_owner::_xdebugrecord1_owner() { jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { if( p_struct!=NULL ) { alglib_impl::_xdebugrecord1_destroy(p_struct); alglib_impl::ae_free(p_struct); } p_struct = NULL; #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); p_struct = NULL; p_struct = (alglib_impl::xdebugrecord1*)alglib_impl::ae_malloc(sizeof(alglib_impl::xdebugrecord1), &_state); memset(p_struct, 0, sizeof(alglib_impl::xdebugrecord1)); alglib_impl::_xdebugrecord1_init(p_struct, &_state, ae_false); ae_state_clear(&_state); } _xdebugrecord1_owner::_xdebugrecord1_owner(const _xdebugrecord1_owner &rhs) { jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { if( p_struct!=NULL ) { alglib_impl::_xdebugrecord1_destroy(p_struct); alglib_impl::ae_free(p_struct); } p_struct = NULL; #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); p_struct = NULL; alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: xdebugrecord1 copy constructor failure (source is not initialized)", &_state); p_struct = (alglib_impl::xdebugrecord1*)alglib_impl::ae_malloc(sizeof(alglib_impl::xdebugrecord1), &_state); memset(p_struct, 0, sizeof(alglib_impl::xdebugrecord1)); alglib_impl::_xdebugrecord1_init_copy(p_struct, const_cast(rhs.p_struct), &_state, ae_false); ae_state_clear(&_state); } _xdebugrecord1_owner& _xdebugrecord1_owner::operator=(const _xdebugrecord1_owner &rhs) { if( this==&rhs ) return *this; jmp_buf _break_jump; alglib_impl::ae_state _state; alglib_impl::ae_state_init(&_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_state.error_msg); return *this; #endif } alglib_impl::ae_state_set_break_jump(&_state, &_break_jump); alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: xdebugrecord1 assignment constructor failure (destination is not initialized)", &_state); alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: xdebugrecord1 assignment constructor failure (source is not initialized)", &_state); alglib_impl::_xdebugrecord1_destroy(p_struct); memset(p_struct, 0, sizeof(alglib_impl::xdebugrecord1)); alglib_impl::_xdebugrecord1_init_copy(p_struct, const_cast(rhs.p_struct), &_state, ae_false); ae_state_clear(&_state); return *this; } _xdebugrecord1_owner::~_xdebugrecord1_owner() { if( p_struct!=NULL ) { alglib_impl::_xdebugrecord1_destroy(p_struct); ae_free(p_struct); } } alglib_impl::xdebugrecord1* _xdebugrecord1_owner::c_ptr() { return p_struct; } alglib_impl::xdebugrecord1* _xdebugrecord1_owner::c_ptr() const { return const_cast(p_struct); } xdebugrecord1::xdebugrecord1() : _xdebugrecord1_owner() ,i(p_struct->i),c(*((alglib::complex*)(&p_struct->c))),a(&p_struct->a) { } xdebugrecord1::xdebugrecord1(const xdebugrecord1 &rhs):_xdebugrecord1_owner(rhs) ,i(p_struct->i),c(*((alglib::complex*)(&p_struct->c))),a(&p_struct->a) { } xdebugrecord1& xdebugrecord1::operator=(const xdebugrecord1 &rhs) { if( this==&rhs ) return *this; _xdebugrecord1_owner::operator=(rhs); return *this; } xdebugrecord1::~xdebugrecord1() { } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Creates and returns XDebugRecord1 structure: * integer and complex fields of Rec1 are set to 1 and 1+i correspondingly * array field of Rec1 is set to [2,3] -- ALGLIB -- Copyright 27.05.2014 by Bochkanov Sergey *************************************************************************/ void xdebuginitrecord1(xdebugrecord1 &rec1, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebuginitrecord1(const_cast(rec1.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Counts number of True values in the boolean 1D array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ ae_int_t xdebugb1count(const boolean_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::xdebugb1count(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by NOT(a[i]). Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb1not(const boolean_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugb1not(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Appends copy of array to itself. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb1appendcopy(boolean_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugb1appendcopy(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate N-element array with even-numbered elements set to True. Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb1outeven(const ae_int_t n, boolean_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugb1outeven(n, const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ ae_int_t xdebugi1sum(const integer_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::xdebugi1sum(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -A[I] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi1neg(const integer_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugi1neg(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Appends copy of array to itself. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi1appendcopy(integer_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugi1appendcopy(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate N-element array with even-numbered A[I] set to I, and odd-numbered ones set to 0. Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi1outeven(const ae_int_t n, integer_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugi1outeven(n, const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ double xdebugr1sum(const real_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); double result = alglib_impl::xdebugr1sum(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -A[I] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr1neg(const real_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugr1neg(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Appends copy of array to itself. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr1appendcopy(real_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugr1appendcopy(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate N-element array with even-numbered A[I] set to I*0.25, and odd-numbered ones are set to 0. Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr1outeven(const ae_int_t n, real_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugr1outeven(n, const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ alglib::complex xdebugc1sum(const complex_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_complex result = alglib_impl::xdebugc1sum(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -A[I] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc1neg(const complex_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugc1neg(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Appends copy of array to itself. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc1appendcopy(complex_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugc1appendcopy(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate N-element array with even-numbered A[K] set to (x,y) = (K*0.25, K*0.125) and odd-numbered ones are set to 0. Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc1outeven(const ae_int_t n, complex_1d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugc1outeven(n, const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Counts number of True values in the boolean 2D array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ ae_int_t xdebugb2count(const boolean_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::xdebugb2count(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by NOT(a[i]). Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb2not(const boolean_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugb2not(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Transposes array. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb2transpose(boolean_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugb2transpose(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate MxN matrix with elements set to "Sin(3*I+5*J)>0" Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb2outsin(const ae_int_t m, const ae_int_t n, boolean_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugb2outsin(m, n, const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ ae_int_t xdebugi2sum(const integer_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_int_t result = alglib_impl::xdebugi2sum(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -a[i,j] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi2neg(const integer_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugi2neg(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Transposes array. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi2transpose(integer_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugi2transpose(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate MxN matrix with elements set to "Sign(Sin(3*I+5*J))" Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi2outsin(const ae_int_t m, const ae_int_t n, integer_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugi2outsin(m, n, const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ double xdebugr2sum(const real_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); double result = alglib_impl::xdebugr2sum(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -a[i,j] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr2neg(const real_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugr2neg(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Transposes array. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr2transpose(real_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugr2transpose(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate MxN matrix with elements set to "Sin(3*I+5*J)" Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr2outsin(const ae_int_t m, const ae_int_t n, real_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugr2outsin(m, n, const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ alglib::complex xdebugc2sum(const complex_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::ae_complex result = alglib_impl::xdebugc2sum(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -a[i,j] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc2neg(const complex_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugc2neg(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Transposes array. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc2transpose(complex_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugc2transpose(const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate MxN matrix with elements set to "Sin(3*I+5*J),Cos(3*I+5*J)" Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc2outsincos(const ae_int_t m, const ae_int_t n, complex_2d_array &a, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); alglib_impl::xdebugc2outsincos(m, n, const_cast(a.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of a[i,j]*(1+b[i,j]) such that c[i,j] is True -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ double xdebugmaskedbiasedproductsum(const ae_int_t m, const ae_int_t n, const real_2d_array &a, const real_2d_array &b, const boolean_2d_array &c, const xparams _xparams) { jmp_buf _break_jump; alglib_impl::ae_state _alglib_env_state; alglib_impl::ae_state_init(&_alglib_env_state); if( setjmp(_break_jump) ) { #if !defined(AE_NO_EXCEPTIONS) _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg); #else _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg); return 0; #endif } ae_state_set_break_jump(&_alglib_env_state, &_break_jump); if( _xparams.flags!=0x0 ) ae_state_set_flags(&_alglib_env_state, _xparams.flags); double result = alglib_impl::xdebugmaskedbiasedproductsum(m, n, const_cast(a.c_ptr()), const_cast(b.c_ptr()), const_cast(c.c_ptr()), &_alglib_env_state); alglib_impl::ae_state_clear(&_alglib_env_state); return *(reinterpret_cast(&result)); } #endif } ///////////////////////////////////////////////////////////////////////// // // THIS SECTION CONTAINS IMPLEMENTATION OF COMPUTATIONAL CORE // ///////////////////////////////////////////////////////////////////////// namespace alglib_impl { #if defined(AE_COMPILE_NEARESTNEIGHBOR) || !defined(AE_PARTIAL_BUILD) static ae_int_t nearestneighbor_splitnodesize = 6; static ae_int_t nearestneighbor_kdtreefirstversion = 0; static ae_int_t nearestneighbor_tsqueryrnn(kdtree* kdt, kdtreerequestbuffer* buf, /* Real */ ae_vector* x, double r, ae_bool selfmatch, ae_bool orderedbydist, ae_state *_state); static void nearestneighbor_kdtreesplit(kdtree* kdt, ae_int_t i1, ae_int_t i2, ae_int_t d, double s, ae_int_t* i3, ae_state *_state); static void nearestneighbor_kdtreegeneratetreerec(kdtree* kdt, ae_int_t* nodesoffs, ae_int_t* splitsoffs, ae_int_t i1, ae_int_t i2, ae_int_t maxleafsize, ae_state *_state); static void nearestneighbor_kdtreequerynnrec(kdtree* kdt, kdtreerequestbuffer* buf, ae_int_t offs, ae_state *_state); static void nearestneighbor_kdtreequeryboxrec(kdtree* kdt, kdtreerequestbuffer* buf, ae_int_t offs, ae_state *_state); static void nearestneighbor_kdtreeinitbox(kdtree* kdt, /* Real */ ae_vector* x, kdtreerequestbuffer* buf, ae_state *_state); static void nearestneighbor_kdtreeallocdatasetindependent(kdtree* kdt, ae_int_t nx, ae_int_t ny, ae_state *_state); static void nearestneighbor_kdtreeallocdatasetdependent(kdtree* kdt, ae_int_t n, ae_int_t nx, ae_int_t ny, ae_state *_state); static void nearestneighbor_checkrequestbufferconsistency(kdtree* kdt, kdtreerequestbuffer* buf, ae_state *_state); #endif #if defined(AE_COMPILE_HQRND) || !defined(AE_PARTIAL_BUILD) static ae_int_t hqrnd_hqrndmax = 2147483561; static ae_int_t hqrnd_hqrndm1 = 2147483563; static ae_int_t hqrnd_hqrndm2 = 2147483399; static ae_int_t hqrnd_hqrndmagic = 1634357784; static ae_int_t hqrnd_hqrndintegerbase(hqrndstate* state, ae_state *_state); #endif #if defined(AE_COMPILE_XDEBUG) || !defined(AE_PARTIAL_BUILD) #endif #if defined(AE_COMPILE_NEARESTNEIGHBOR) || !defined(AE_PARTIAL_BUILD) /************************************************************************* KD-tree creation This subroutine creates KD-tree from set of X-values and optional Y-values INPUT PARAMETERS XY - dataset, array[0..N-1,0..NX+NY-1]. one row corresponds to one point. first NX columns contain X-values, next NY (NY may be zero) columns may contain associated Y-values N - number of points, N>=0. NX - space dimension, NX>=1. NY - number of optional Y-values, NY>=0. NormType- norm type: * 0 denotes infinity-norm * 1 denotes 1-norm * 2 denotes 2-norm (Euclidean norm) OUTPUT PARAMETERS KDT - KD-tree NOTES 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory requirements. 2. Although KD-trees may be used with any combination of N and NX, they are more efficient than brute-force search only when N >> 4^NX. So they are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another inefficient case, because simple binary search (without additional structures) is much more efficient in such tasks than KD-trees. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreebuild(/* Real */ ae_matrix* xy, ae_int_t n, ae_int_t nx, ae_int_t ny, ae_int_t normtype, kdtree* kdt, ae_state *_state) { ae_frame _frame_block; ae_vector tags; ae_int_t i; ae_frame_make(_state, &_frame_block); memset(&tags, 0, sizeof(tags)); _kdtree_clear(kdt); ae_vector_init(&tags, 0, DT_INT, _state, ae_true); ae_assert(n>=0, "KDTreeBuild: N<0", _state); ae_assert(nx>=1, "KDTreeBuild: NX<1", _state); ae_assert(ny>=0, "KDTreeBuild: NY<0", _state); ae_assert(normtype>=0&&normtype<=2, "KDTreeBuild: incorrect NormType", _state); ae_assert(xy->rows>=n, "KDTreeBuild: rows(X)cols>=nx+ny||n==0, "KDTreeBuild: cols(X)0 ) { ae_vector_set_length(&tags, n, _state); for(i=0; i<=n-1; i++) { tags.ptr.p_int[i] = 0; } } kdtreebuildtagged(xy, &tags, n, nx, ny, normtype, kdt, _state); ae_frame_leave(_state); } /************************************************************************* KD-tree creation This subroutine creates KD-tree from set of X-values, integer tags and optional Y-values INPUT PARAMETERS XY - dataset, array[0..N-1,0..NX+NY-1]. one row corresponds to one point. first NX columns contain X-values, next NY (NY may be zero) columns may contain associated Y-values Tags - tags, array[0..N-1], contains integer tags associated with points. N - number of points, N>=0 NX - space dimension, NX>=1. NY - number of optional Y-values, NY>=0. NormType- norm type: * 0 denotes infinity-norm * 1 denotes 1-norm * 2 denotes 2-norm (Euclidean norm) OUTPUT PARAMETERS KDT - KD-tree NOTES 1. KD-tree creation have O(N*logN) complexity and O(N*(2*NX+NY)) memory requirements. 2. Although KD-trees may be used with any combination of N and NX, they are more efficient than brute-force search only when N >> 4^NX. So they are most useful in low-dimensional tasks (NX=2, NX=3). NX=1 is another inefficient case, because simple binary search (without additional structures) is much more efficient in such tasks than KD-trees. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreebuildtagged(/* Real */ ae_matrix* xy, /* Integer */ ae_vector* tags, ae_int_t n, ae_int_t nx, ae_int_t ny, ae_int_t normtype, kdtree* kdt, ae_state *_state) { ae_int_t i; ae_int_t j; ae_int_t nodesoffs; ae_int_t splitsoffs; _kdtree_clear(kdt); ae_assert(n>=0, "KDTreeBuildTagged: N<0", _state); ae_assert(nx>=1, "KDTreeBuildTagged: NX<1", _state); ae_assert(ny>=0, "KDTreeBuildTagged: NY<0", _state); ae_assert(normtype>=0&&normtype<=2, "KDTreeBuildTagged: incorrect NormType", _state); ae_assert(xy->rows>=n, "KDTreeBuildTagged: rows(X)cols>=nx+ny||n==0, "KDTreeBuildTagged: cols(X)n = n; kdt->nx = nx; kdt->ny = ny; kdt->normtype = normtype; kdt->innerbuf.kcur = 0; /* * N=0 => quick exit */ if( n==0 ) { return; } /* * Allocate */ nearestneighbor_kdtreeallocdatasetindependent(kdt, nx, ny, _state); nearestneighbor_kdtreeallocdatasetdependent(kdt, n, nx, ny, _state); kdtreecreaterequestbuffer(kdt, &kdt->innerbuf, _state); /* * Initial fill */ for(i=0; i<=n-1; i++) { ae_v_move(&kdt->xy.ptr.pp_double[i][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nx-1)); 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)); kdt->tags.ptr.p_int[i] = tags->ptr.p_int[i]; } /* * Determine bounding box */ ae_v_move(&kdt->boxmin.ptr.p_double[0], 1, &kdt->xy.ptr.pp_double[0][0], 1, ae_v_len(0,nx-1)); ae_v_move(&kdt->boxmax.ptr.p_double[0], 1, &kdt->xy.ptr.pp_double[0][0], 1, ae_v_len(0,nx-1)); for(i=1; i<=n-1; i++) { for(j=0; j<=nx-1; j++) { kdt->boxmin.ptr.p_double[j] = ae_minreal(kdt->boxmin.ptr.p_double[j], kdt->xy.ptr.pp_double[i][j], _state); kdt->boxmax.ptr.p_double[j] = ae_maxreal(kdt->boxmax.ptr.p_double[j], kdt->xy.ptr.pp_double[i][j], _state); } } /* * Generate tree */ nodesoffs = 0; splitsoffs = 0; ae_v_move(&kdt->innerbuf.curboxmin.ptr.p_double[0], 1, &kdt->boxmin.ptr.p_double[0], 1, ae_v_len(0,nx-1)); ae_v_move(&kdt->innerbuf.curboxmax.ptr.p_double[0], 1, &kdt->boxmax.ptr.p_double[0], 1, ae_v_len(0,nx-1)); nearestneighbor_kdtreegeneratetreerec(kdt, &nodesoffs, &splitsoffs, 0, n, 8, _state); ivectorresize(&kdt->nodes, nodesoffs, _state); rvectorresize(&kdt->splits, splitsoffs, _state); } /************************************************************************* This function creates buffer structure which can be used to perform parallel KD-tree requests. KD-tree subpackage provides two sets of request functions - ones which use internal buffer of KD-tree object (these functions are single-threaded because they use same buffer, which can not shared between threads), and ones which use external buffer. This function is used to initialize external buffer. INPUT PARAMETERS KDT - KD-tree which is associated with newly created buffer OUTPUT PARAMETERS Buf - external buffer. IMPORTANT: KD-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use buffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ void kdtreecreaterequestbuffer(kdtree* kdt, kdtreerequestbuffer* buf, ae_state *_state) { _kdtreerequestbuffer_clear(buf); ae_vector_set_length(&buf->x, kdt->nx, _state); ae_vector_set_length(&buf->boxmin, kdt->nx, _state); ae_vector_set_length(&buf->boxmax, kdt->nx, _state); ae_vector_set_length(&buf->idx, kdt->n, _state); ae_vector_set_length(&buf->r, kdt->n, _state); ae_vector_set_length(&buf->buf, ae_maxint(kdt->n, kdt->nx, _state), _state); ae_vector_set_length(&buf->curboxmin, kdt->nx, _state); ae_vector_set_length(&buf->curboxmax, kdt->nx, _state); buf->kcur = 0; } /************************************************************************* K-NN query: K nearest neighbors IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: KDTreeTsQueryKNN() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of actual neighbors found (either K or N, if K>N). This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain these results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreequeryknn(kdtree* kdt, /* Real */ ae_vector* x, ae_int_t k, ae_bool selfmatch, ae_state *_state) { ae_int_t result; ae_assert(k>=1, "KDTreeQueryKNN: K<1!", _state); ae_assert(x->cnt>=kdt->nx, "KDTreeQueryKNN: Length(X)nx, _state), "KDTreeQueryKNN: X contains infinite or NaN values!", _state); result = kdtreetsqueryaknn(kdt, &kdt->innerbuf, x, k, selfmatch, 0.0, _state); return result; } /************************************************************************* K-NN query: K nearest neighbors, using external thread-local buffer. You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - kd-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of actual neighbors found (either K or N, if K>N). This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreetsqueryknn(kdtree* kdt, kdtreerequestbuffer* buf, /* Real */ ae_vector* x, ae_int_t k, ae_bool selfmatch, ae_state *_state) { ae_int_t result; ae_assert(k>=1, "KDTreeTsQueryKNN: K<1!", _state); ae_assert(x->cnt>=kdt->nx, "KDTreeTsQueryKNN: Length(X)nx, _state), "KDTreeTsQueryKNN: X contains infinite or NaN values!", _state); result = kdtreetsqueryaknn(kdt, buf, x, k, selfmatch, 0.0, _state); return result; } /************************************************************************* R-NN query: all points within R-sphere centered at X, ordered by distance between point and X (by ascending). NOTE: it is also possible to perform undordered queries performed by means of kdtreequeryrnnu() and kdtreetsqueryrnnu() functions. Such queries are faster because we do not have to use heap structure for sorting. IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: kdtreetsqueryrnn() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain actual results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreequeryrnn(kdtree* kdt, /* Real */ ae_vector* x, double r, ae_bool selfmatch, ae_state *_state) { ae_int_t result; ae_assert(ae_fp_greater(r,(double)(0)), "KDTreeQueryRNN: incorrect R!", _state); ae_assert(x->cnt>=kdt->nx, "KDTreeQueryRNN: Length(X)nx, _state), "KDTreeQueryRNN: X contains infinite or NaN values!", _state); result = kdtreetsqueryrnn(kdt, &kdt->innerbuf, x, r, selfmatch, _state); return result; } /************************************************************************* R-NN query: all points within R-sphere centered at X, no ordering by distance as undicated by "U" suffix (faster that ordered query, for large queries - significantly faster). IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: kdtreetsqueryrnn() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain actual results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances As indicated by "U" suffix, this function returns unordered results. -- ALGLIB -- Copyright 01.11.2018 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreequeryrnnu(kdtree* kdt, /* Real */ ae_vector* x, double r, ae_bool selfmatch, ae_state *_state) { ae_int_t result; ae_assert(ae_fp_greater(r,(double)(0)), "KDTreeQueryRNNU: incorrect R!", _state); ae_assert(x->cnt>=kdt->nx, "KDTreeQueryRNNU: Length(X)nx, _state), "KDTreeQueryRNNU: X contains infinite or NaN values!", _state); result = kdtreetsqueryrnnu(kdt, &kdt->innerbuf, x, r, selfmatch, _state); return result; } /************************************************************************* R-NN query: all points within R-sphere centered at X, using external thread-local buffer, sorted by distance between point and X (by ascending) You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. NOTE: it is also possible to perform undordered queries performed by means of kdtreequeryrnnu() and kdtreetsqueryrnnu() functions. Such queries are faster because we do not have to use heap structure for sorting. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreetsqueryrnn(kdtree* kdt, kdtreerequestbuffer* buf, /* Real */ ae_vector* x, double r, ae_bool selfmatch, ae_state *_state) { ae_int_t result; ae_assert(ae_isfinite(r, _state)&&ae_fp_greater(r,(double)(0)), "KDTreeTsQueryRNN: incorrect R!", _state); ae_assert(x->cnt>=kdt->nx, "KDTreeTsQueryRNN: Length(X)nx, _state), "KDTreeTsQueryRNN: X contains infinite or NaN values!", _state); result = nearestneighbor_tsqueryrnn(kdt, buf, x, r, selfmatch, ae_true, _state); return result; } /************************************************************************* R-NN query: all points within R-sphere centered at X, using external thread-local buffer, no ordering by distance as undicated by "U" suffix (faster that ordered query, for large queries - significantly faster). You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances As indicated by "U" suffix, this function returns unordered results. IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreetsqueryrnnu(kdtree* kdt, kdtreerequestbuffer* buf, /* Real */ ae_vector* x, double r, ae_bool selfmatch, ae_state *_state) { ae_int_t result; ae_assert(ae_isfinite(r, _state)&&ae_fp_greater(r,(double)(0)), "KDTreeTsQueryRNNU: incorrect R!", _state); ae_assert(x->cnt>=kdt->nx, "KDTreeTsQueryRNNU: Length(X)nx, _state), "KDTreeTsQueryRNNU: X contains infinite or NaN values!", _state); result = nearestneighbor_tsqueryrnn(kdt, buf, x, r, selfmatch, ae_false, _state); return result; } /************************************************************************* K-NN query: approximate K nearest neighbors IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: KDTreeTsQueryAKNN() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True Eps - approximation factor, Eps>=0. eps-approximate nearest neighbor is a neighbor whose distance from X is at most (1+eps) times distance of true nearest neighbor. RESULT number of actual neighbors found (either K or N, if K>N). NOTES significant performance gain may be achieved only when Eps is is on the order of magnitude of 1 or larger. This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain these results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() to get distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreequeryaknn(kdtree* kdt, /* Real */ ae_vector* x, ae_int_t k, ae_bool selfmatch, double eps, ae_state *_state) { ae_int_t result; result = kdtreetsqueryaknn(kdt, &kdt->innerbuf, x, k, selfmatch, eps, _state); return result; } /************************************************************************* K-NN query: approximate K nearest neighbors, using thread-local buffer. You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. K - number of neighbors to return, K>=1 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True Eps - approximation factor, Eps>=0. eps-approximate nearest neighbor is a neighbor whose distance from X is at most (1+eps) times distance of true nearest neighbor. RESULT number of actual neighbors found (either K or N, if K>N). NOTES significant performance gain may be achieved only when Eps is is on the order of magnitude of 1 or larger. This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreetsqueryaknn(kdtree* kdt, kdtreerequestbuffer* buf, /* Real */ ae_vector* x, ae_int_t k, ae_bool selfmatch, double eps, ae_state *_state) { ae_int_t i; ae_int_t j; ae_int_t result; ae_assert(k>0, "KDTreeTsQueryAKNN: incorrect K!", _state); ae_assert(ae_fp_greater_eq(eps,(double)(0)), "KDTreeTsQueryAKNN: incorrect Eps!", _state); ae_assert(x->cnt>=kdt->nx, "KDTreeTsQueryAKNN: Length(X)nx, _state), "KDTreeTsQueryAKNN: X contains infinite or NaN values!", _state); /* * Handle special case: KDT.N=0 */ if( kdt->n==0 ) { buf->kcur = 0; result = 0; return result; } /* * Check consistency of request buffer */ nearestneighbor_checkrequestbufferconsistency(kdt, buf, _state); /* * Prepare parameters */ k = ae_minint(k, kdt->n, _state); buf->kneeded = k; buf->rneeded = (double)(0); buf->selfmatch = selfmatch; if( kdt->normtype==2 ) { buf->approxf = 1/ae_sqr(1+eps, _state); } else { buf->approxf = 1/(1+eps); } buf->kcur = 0; /* * calculate distance from point to current bounding box */ nearestneighbor_kdtreeinitbox(kdt, x, buf, _state); /* * call recursive search * results are returned as heap */ nearestneighbor_kdtreequerynnrec(kdt, buf, 0, _state); /* * pop from heap to generate ordered representation * * last element is non pop'ed because it is already in * its place */ result = buf->kcur; j = buf->kcur; for(i=buf->kcur; i>=2; i--) { tagheappopi(&buf->r, &buf->idx, &j, _state); } return result; } /************************************************************************* Box query: all points within user-specified box. IMPORTANT: this function can not be used in multithreaded code because it uses internal temporary buffer of kd-tree object, which can not be shared between multiple threads. If you want to perform parallel requests, use function which uses external request buffer: KDTreeTsQueryBox() ("Ts" stands for "thread-safe"). INPUT PARAMETERS KDT - KD-tree BoxMin - lower bounds, array[0..NX-1]. BoxMax - upper bounds, array[0..NX-1]. RESULT number of actual neighbors found (in [0,N]). This subroutine performs query and stores its result in the internal structures of the KD-tree. You can use following subroutines to obtain these results: * KDTreeQueryResultsX() to get X-values * KDTreeQueryResultsXY() to get X- and Y-values * KDTreeQueryResultsTags() to get tag values * KDTreeQueryResultsDistances() returns zeros for this request NOTE: this particular query returns unordered results, because there is no meaningful way of ordering points. Furthermore, no 'distance' is associated with points - it is either INSIDE or OUTSIDE (so request for distances will return zeros). -- ALGLIB -- Copyright 14.05.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreequerybox(kdtree* kdt, /* Real */ ae_vector* boxmin, /* Real */ ae_vector* boxmax, ae_state *_state) { ae_int_t result; result = kdtreetsquerybox(kdt, &kdt->innerbuf, boxmin, boxmax, _state); return result; } /************************************************************************* Box query: all points within user-specified box, using thread-local buffer. You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. BoxMin - lower bounds, array[0..NX-1]. BoxMax - upper bounds, array[0..NX-1]. RESULT number of actual neighbors found (in [0,N]). This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "ts" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() returns zeros for this query NOTE: this particular query returns unordered results, because there is no meaningful way of ordering points. Furthermore, no 'distance' is associated with points - it is either INSIDE or OUTSIDE (so request for distances will return zeros). IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 14.05.2016 by Bochkanov Sergey *************************************************************************/ ae_int_t kdtreetsquerybox(kdtree* kdt, kdtreerequestbuffer* buf, /* Real */ ae_vector* boxmin, /* Real */ ae_vector* boxmax, ae_state *_state) { ae_int_t j; ae_int_t result; ae_assert(boxmin->cnt>=kdt->nx, "KDTreeTsQueryBox: Length(BoxMin)cnt>=kdt->nx, "KDTreeTsQueryBox: Length(BoxMax)nx, _state), "KDTreeTsQueryBox: BoxMin contains infinite or NaN values!", _state); ae_assert(isfinitevector(boxmax, kdt->nx, _state), "KDTreeTsQueryBox: BoxMax contains infinite or NaN values!", _state); /* * Check consistency of request buffer */ nearestneighbor_checkrequestbufferconsistency(kdt, buf, _state); /* * Quick exit for degenerate boxes */ for(j=0; j<=kdt->nx-1; j++) { if( ae_fp_greater(boxmin->ptr.p_double[j],boxmax->ptr.p_double[j]) ) { buf->kcur = 0; result = 0; return result; } } /* * Prepare parameters */ for(j=0; j<=kdt->nx-1; j++) { buf->boxmin.ptr.p_double[j] = boxmin->ptr.p_double[j]; buf->boxmax.ptr.p_double[j] = boxmax->ptr.p_double[j]; buf->curboxmin.ptr.p_double[j] = boxmin->ptr.p_double[j]; buf->curboxmax.ptr.p_double[j] = boxmax->ptr.p_double[j]; } buf->kcur = 0; /* * call recursive search */ nearestneighbor_kdtreequeryboxrec(kdt, buf, 0, _state); result = buf->kcur; return result; } /************************************************************************* X-values from last query. This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - kdtreetsqueryresultsx(). INPUT PARAMETERS KDT - KD-tree X - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS X - rows are filled with X-values NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsTags() tag values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsx(kdtree* kdt, /* Real */ ae_matrix* x, ae_state *_state) { kdtreetsqueryresultsx(kdt, &kdt->innerbuf, x, _state); } /************************************************************************* X- and Y-values from last query This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - kdtreetsqueryresultsxy(). INPUT PARAMETERS KDT - KD-tree XY - possibly pre-allocated buffer. If XY is too small to store result, it is resized. If size(XY) is enough to store result, it is left unchanged. OUTPUT PARAMETERS XY - rows are filled with points: first NX columns with X-values, next NY columns - with Y-values. NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsTags() tag values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsxy(kdtree* kdt, /* Real */ ae_matrix* xy, ae_state *_state) { kdtreetsqueryresultsxy(kdt, &kdt->innerbuf, xy, _state); } /************************************************************************* Tags from last query This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - kdtreetsqueryresultstags(). INPUT PARAMETERS KDT - KD-tree Tags - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS Tags - filled with tags associated with points, or, when no tags were supplied, with zeros NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultstags(kdtree* kdt, /* Integer */ ae_vector* tags, ae_state *_state) { kdtreetsqueryresultstags(kdt, &kdt->innerbuf, tags, _state); } /************************************************************************* Distances from last query This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - kdtreetsqueryresultsdistances(). INPUT PARAMETERS KDT - KD-tree R - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS R - filled with distances (in corresponding norm) NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsTags() tag values -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsdistances(kdtree* kdt, /* Real */ ae_vector* r, ae_state *_state) { kdtreetsqueryresultsdistances(kdt, &kdt->innerbuf, r, _state); } /************************************************************************* X-values from last query associated with kdtreerequestbuffer object. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure. X - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS X - rows are filled with X-values NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsTags() tag values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreetsqueryresultsx(kdtree* kdt, kdtreerequestbuffer* buf, /* Real */ ae_matrix* x, ae_state *_state) { ae_int_t i; ae_int_t k; if( buf->kcur==0 ) { return; } if( x->rowskcur||x->colsnx ) { ae_matrix_set_length(x, buf->kcur, kdt->nx, _state); } k = buf->kcur; for(i=0; i<=k-1; i++) { ae_v_move(&x->ptr.pp_double[i][0], 1, &kdt->xy.ptr.pp_double[buf->idx.ptr.p_int[i]][kdt->nx], 1, ae_v_len(0,kdt->nx-1)); } } /************************************************************************* X- and Y-values from last query associated with kdtreerequestbuffer object. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure. XY - possibly pre-allocated buffer. If XY is too small to store result, it is resized. If size(XY) is enough to store result, it is left unchanged. OUTPUT PARAMETERS XY - rows are filled with points: first NX columns with X-values, next NY columns - with Y-values. NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsTags() tag values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreetsqueryresultsxy(kdtree* kdt, kdtreerequestbuffer* buf, /* Real */ ae_matrix* xy, ae_state *_state) { ae_int_t i; ae_int_t k; if( buf->kcur==0 ) { return; } if( xy->rowskcur||xy->colsnx+kdt->ny ) { ae_matrix_set_length(xy, buf->kcur, kdt->nx+kdt->ny, _state); } k = buf->kcur; for(i=0; i<=k-1; i++) { ae_v_move(&xy->ptr.pp_double[i][0], 1, &kdt->xy.ptr.pp_double[buf->idx.ptr.p_int[i]][kdt->nx], 1, ae_v_len(0,kdt->nx+kdt->ny-1)); } } /************************************************************************* Tags from last query associated with kdtreerequestbuffer object. This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - KDTreeTsqueryresultstags(). INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure. Tags - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS Tags - filled with tags associated with points, or, when no tags were supplied, with zeros NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsDistances() distances -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreetsqueryresultstags(kdtree* kdt, kdtreerequestbuffer* buf, /* Integer */ ae_vector* tags, ae_state *_state) { ae_int_t i; ae_int_t k; if( buf->kcur==0 ) { return; } if( tags->cntkcur ) { ae_vector_set_length(tags, buf->kcur, _state); } k = buf->kcur; for(i=0; i<=k-1; i++) { tags->ptr.p_int[i] = kdt->tags.ptr.p_int[buf->idx.ptr.p_int[i]]; } } /************************************************************************* Distances from last query associated with kdtreerequestbuffer object. This function retuns results stored in the internal buffer of kd-tree object. If you performed buffered requests (ones which use instances of kdtreerequestbuffer class), you should call buffered version of this function - KDTreeTsqueryresultsdistances(). INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure. R - possibly pre-allocated buffer. If X is too small to store result, it is resized. If size(X) is enough to store result, it is left unchanged. OUTPUT PARAMETERS R - filled with distances (in corresponding norm) NOTES 1. points are ordered by distance from the query point (first = closest) 2. if XY is larger than required to store result, only leading part will be overwritten; trailing part will be left unchanged. So if on input XY = [[A,B],[C,D]], and result is [1,2], then on exit we will get XY = [[1,2],[C,D]]. This is done purposely to increase performance; if you want function to resize array according to result size, use function with same name and suffix 'I'. SEE ALSO * KDTreeQueryResultsX() X-values * KDTreeQueryResultsXY() X- and Y-values * KDTreeQueryResultsTags() tag values -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreetsqueryresultsdistances(kdtree* kdt, kdtreerequestbuffer* buf, /* Real */ ae_vector* r, ae_state *_state) { ae_int_t i; ae_int_t k; if( buf->kcur==0 ) { return; } if( r->cntkcur ) { ae_vector_set_length(r, buf->kcur, _state); } k = buf->kcur; /* * unload norms * * Abs() call is used to handle cases with negative norms * (generated during KFN requests) */ if( kdt->normtype==0 ) { for(i=0; i<=k-1; i++) { r->ptr.p_double[i] = ae_fabs(buf->r.ptr.p_double[i], _state); } } if( kdt->normtype==1 ) { for(i=0; i<=k-1; i++) { r->ptr.p_double[i] = ae_fabs(buf->r.ptr.p_double[i], _state); } } if( kdt->normtype==2 ) { for(i=0; i<=k-1; i++) { r->ptr.p_double[i] = ae_sqrt(ae_fabs(buf->r.ptr.p_double[i], _state), _state); } } } /************************************************************************* X-values from last query; 'interactive' variant for languages like Python which support constructs like "X = KDTreeQueryResultsXI(KDT)" and interactive mode of interpreter. This function allocates new array on each call, so it is significantly slower than its 'non-interactive' counterpart, but it is more convenient when you call it from command line. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsxi(kdtree* kdt, /* Real */ ae_matrix* x, ae_state *_state) { ae_matrix_clear(x); kdtreequeryresultsx(kdt, x, _state); } /************************************************************************* XY-values from last query; 'interactive' variant for languages like Python which support constructs like "XY = KDTreeQueryResultsXYI(KDT)" and interactive mode of interpreter. This function allocates new array on each call, so it is significantly slower than its 'non-interactive' counterpart, but it is more convenient when you call it from command line. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsxyi(kdtree* kdt, /* Real */ ae_matrix* xy, ae_state *_state) { ae_matrix_clear(xy); kdtreequeryresultsxy(kdt, xy, _state); } /************************************************************************* Tags from last query; 'interactive' variant for languages like Python which support constructs like "Tags = KDTreeQueryResultsTagsI(KDT)" and interactive mode of interpreter. This function allocates new array on each call, so it is significantly slower than its 'non-interactive' counterpart, but it is more convenient when you call it from command line. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultstagsi(kdtree* kdt, /* Integer */ ae_vector* tags, ae_state *_state) { ae_vector_clear(tags); kdtreequeryresultstags(kdt, tags, _state); } /************************************************************************* Distances from last query; 'interactive' variant for languages like Python which support constructs like "R = KDTreeQueryResultsDistancesI(KDT)" and interactive mode of interpreter. This function allocates new array on each call, so it is significantly slower than its 'non-interactive' counterpart, but it is more convenient when you call it from command line. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ void kdtreequeryresultsdistancesi(kdtree* kdt, /* Real */ ae_vector* r, ae_state *_state) { ae_vector_clear(r); kdtreequeryresultsdistances(kdt, r, _state); } /************************************************************************* It is informational function which returns bounding box for entire dataset. This function is not visible to ALGLIB users, only ALGLIB itself may use it. This function assumes that output buffers are preallocated by caller. -- ALGLIB -- Copyright 20.06.2016 by Bochkanov Sergey *************************************************************************/ void kdtreeexplorebox(kdtree* kdt, /* Real */ ae_vector* boxmin, /* Real */ ae_vector* boxmax, ae_state *_state) { ae_int_t i; rvectorsetlengthatleast(boxmin, kdt->nx, _state); rvectorsetlengthatleast(boxmax, kdt->nx, _state); for(i=0; i<=kdt->nx-1; i++) { boxmin->ptr.p_double[i] = kdt->boxmin.ptr.p_double[i]; boxmax->ptr.p_double[i] = kdt->boxmax.ptr.p_double[i]; } } /************************************************************************* It is informational function which allows to get information about node type. Node index is given by integer value, with 0 corresponding to root node and other node indexes obtained via exploration. You should not expect that serialization/unserialization will retain node indexes. You should keep in mind that future versions of ALGLIB may introduce new node types. OUTPUT VALUES: NodeType - node type: * 0 corresponds to leaf node, which can be explored by kdtreeexploreleaf() function * 1 corresponds to split node, which can be explored by kdtreeexploresplit() function -- ALGLIB -- Copyright 20.06.2016 by Bochkanov Sergey *************************************************************************/ void kdtreeexplorenodetype(kdtree* kdt, ae_int_t node, ae_int_t* nodetype, ae_state *_state) { *nodetype = 0; ae_assert(node>=0, "KDTreeExploreNodeType: incorrect node", _state); ae_assert(nodenodes.cnt, "KDTreeExploreNodeType: incorrect node", _state); if( kdt->nodes.ptr.p_int[node]>0 ) { /* * Leaf node */ *nodetype = 0; return; } if( kdt->nodes.ptr.p_int[node]==0 ) { /* * Split node */ *nodetype = 1; return; } ae_assert(ae_false, "KDTreeExploreNodeType: integrity check failure", _state); } /************************************************************************* It is informational function which allows to get information about leaf node. Node index is given by integer value, with 0 corresponding to root node and other node indexes obtained via exploration. You should not expect that serialization/unserialization will retain node indexes. You should keep in mind that future versions of ALGLIB may introduce new node types. OUTPUT VALUES: XT - output buffer is reallocated (if too small) and filled by XY values K - number of rows in XY -- ALGLIB -- Copyright 20.06.2016 by Bochkanov Sergey *************************************************************************/ void kdtreeexploreleaf(kdtree* kdt, ae_int_t node, /* Real */ ae_matrix* xy, ae_int_t* k, ae_state *_state) { ae_int_t offs; ae_int_t i; ae_int_t j; *k = 0; ae_assert(node>=0, "KDTreeExploreLeaf: incorrect node index", _state); ae_assert(node+1nodes.cnt, "KDTreeExploreLeaf: incorrect node index", _state); ae_assert(kdt->nodes.ptr.p_int[node]>0, "KDTreeExploreLeaf: incorrect node index", _state); *k = kdt->nodes.ptr.p_int[node]; offs = kdt->nodes.ptr.p_int[node+1]; ae_assert(offs>=0, "KDTreeExploreLeaf: integrity error", _state); ae_assert(offs+(*k)-1xy.rows, "KDTreeExploreLeaf: integrity error", _state); rmatrixsetlengthatleast(xy, *k, kdt->nx+kdt->ny, _state); for(i=0; i<=*k-1; i++) { for(j=0; j<=kdt->nx+kdt->ny-1; j++) { xy->ptr.pp_double[i][j] = kdt->xy.ptr.pp_double[offs+i][kdt->nx+j]; } } } /************************************************************************* It is informational function which allows to get information about split node. Node index is given by integer value, with 0 corresponding to root node and other node indexes obtained via exploration. You should not expect that serialization/unserialization will retain node indexes. You should keep in mind that future versions of ALGLIB may introduce new node types. OUTPUT VALUES: XT - output buffer is reallocated (if too small) and filled by XY values K - number of rows in XY // Nodes[idx+1]=dim dimension to split // Nodes[idx+2]=offs offset of splitting point in Splits[] // Nodes[idx+3]=left position of left child in Nodes[] // Nodes[idx+4]=right position of right child in Nodes[] -- ALGLIB -- Copyright 20.06.2016 by Bochkanov Sergey *************************************************************************/ void kdtreeexploresplit(kdtree* kdt, ae_int_t node, ae_int_t* d, double* s, ae_int_t* nodele, ae_int_t* nodege, ae_state *_state) { *d = 0; *s = 0; *nodele = 0; *nodege = 0; ae_assert(node>=0, "KDTreeExploreSplit: incorrect node index", _state); ae_assert(node+4nodes.cnt, "KDTreeExploreSplit: incorrect node index", _state); ae_assert(kdt->nodes.ptr.p_int[node]==0, "KDTreeExploreSplit: incorrect node index", _state); *d = kdt->nodes.ptr.p_int[node+1]; *s = kdt->splits.ptr.p_double[kdt->nodes.ptr.p_int[node+2]]; *nodele = kdt->nodes.ptr.p_int[node+3]; *nodege = kdt->nodes.ptr.p_int[node+4]; ae_assert(*d>=0, "KDTreeExploreSplit: integrity failure", _state); ae_assert(*dnx, "KDTreeExploreSplit: integrity failure", _state); ae_assert(ae_isfinite(*s, _state), "KDTreeExploreSplit: integrity failure", _state); ae_assert(*nodele>=0, "KDTreeExploreSplit: integrity failure", _state); ae_assert(*nodelenodes.cnt, "KDTreeExploreSplit: integrity failure", _state); ae_assert(*nodege>=0, "KDTreeExploreSplit: integrity failure", _state); ae_assert(*nodegenodes.cnt, "KDTreeExploreSplit: integrity failure", _state); } /************************************************************************* Serializer: allocation -- ALGLIB -- Copyright 14.03.2011 by Bochkanov Sergey *************************************************************************/ void kdtreealloc(ae_serializer* s, kdtree* tree, ae_state *_state) { /* * Header */ ae_serializer_alloc_entry(s); ae_serializer_alloc_entry(s); /* * Data */ ae_serializer_alloc_entry(s); ae_serializer_alloc_entry(s); ae_serializer_alloc_entry(s); ae_serializer_alloc_entry(s); allocrealmatrix(s, &tree->xy, -1, -1, _state); allocintegerarray(s, &tree->tags, -1, _state); allocrealarray(s, &tree->boxmin, -1, _state); allocrealarray(s, &tree->boxmax, -1, _state); allocintegerarray(s, &tree->nodes, -1, _state); allocrealarray(s, &tree->splits, -1, _state); } /************************************************************************* Serializer: serialization -- ALGLIB -- Copyright 14.03.2011 by Bochkanov Sergey *************************************************************************/ void kdtreeserialize(ae_serializer* s, kdtree* tree, ae_state *_state) { /* * Header */ ae_serializer_serialize_int(s, getkdtreeserializationcode(_state), _state); ae_serializer_serialize_int(s, nearestneighbor_kdtreefirstversion, _state); /* * Data */ ae_serializer_serialize_int(s, tree->n, _state); ae_serializer_serialize_int(s, tree->nx, _state); ae_serializer_serialize_int(s, tree->ny, _state); ae_serializer_serialize_int(s, tree->normtype, _state); serializerealmatrix(s, &tree->xy, -1, -1, _state); serializeintegerarray(s, &tree->tags, -1, _state); serializerealarray(s, &tree->boxmin, -1, _state); serializerealarray(s, &tree->boxmax, -1, _state); serializeintegerarray(s, &tree->nodes, -1, _state); serializerealarray(s, &tree->splits, -1, _state); } /************************************************************************* Serializer: unserialization -- ALGLIB -- Copyright 14.03.2011 by Bochkanov Sergey *************************************************************************/ void kdtreeunserialize(ae_serializer* s, kdtree* tree, ae_state *_state) { ae_int_t i0; ae_int_t i1; _kdtree_clear(tree); /* * check correctness of header */ ae_serializer_unserialize_int(s, &i0, _state); ae_assert(i0==getkdtreeserializationcode(_state), "KDTreeUnserialize: stream header corrupted", _state); ae_serializer_unserialize_int(s, &i1, _state); ae_assert(i1==nearestneighbor_kdtreefirstversion, "KDTreeUnserialize: stream header corrupted", _state); /* * Unserialize data */ ae_serializer_unserialize_int(s, &tree->n, _state); ae_serializer_unserialize_int(s, &tree->nx, _state); ae_serializer_unserialize_int(s, &tree->ny, _state); ae_serializer_unserialize_int(s, &tree->normtype, _state); unserializerealmatrix(s, &tree->xy, _state); unserializeintegerarray(s, &tree->tags, _state); unserializerealarray(s, &tree->boxmin, _state); unserializerealarray(s, &tree->boxmax, _state); unserializeintegerarray(s, &tree->nodes, _state); unserializerealarray(s, &tree->splits, _state); kdtreecreaterequestbuffer(tree, &tree->innerbuf, _state); } /************************************************************************* R-NN query: all points within R-sphere centered at X, using external thread-local buffer, sorted by distance between point and X (by ascending) You can call this function from multiple threads for same kd-tree instance, assuming that different instances of buffer object are passed to different threads. NOTE: it is also possible to perform undordered queries performed by means of kdtreequeryrnnu() and kdtreetsqueryrnnu() functions. Such queries are faster because we do not have to use heap structure for sorting. INPUT PARAMETERS KDT - KD-tree Buf - request buffer object created for this particular instance of kd-tree structure with kdtreecreaterequestbuffer() function. X - point, array[0..NX-1]. R - radius of sphere (in corresponding norm), R>0 SelfMatch - whether self-matches are allowed: * if True, nearest neighbor may be the point itself (if it exists in original dataset) * if False, then only points with non-zero distance are returned * if not given, considered True RESULT number of neighbors found, >=0 This subroutine performs query and stores its result in the internal structures of the buffer object. You can use following subroutines to obtain these results (pay attention to "buf" in their names): * KDTreeTsQueryResultsX() to get X-values * KDTreeTsQueryResultsXY() to get X- and Y-values * KDTreeTsQueryResultsTags() to get tag values * KDTreeTsQueryResultsDistances() to get distances IMPORTANT: kd-tree buffer should be used only with KD-tree object which was used to initialize buffer. Any attempt to use biffer with different object is dangerous - you may get integrity check failure (exception) because sizes of internal arrays do not fit to dimensions of KD-tree structure. -- ALGLIB -- Copyright 18.03.2016 by Bochkanov Sergey *************************************************************************/ static ae_int_t nearestneighbor_tsqueryrnn(kdtree* kdt, kdtreerequestbuffer* buf, /* Real */ ae_vector* x, double r, ae_bool selfmatch, ae_bool orderedbydist, ae_state *_state) { ae_int_t i; ae_int_t j; ae_int_t result; /* * Handle special case: KDT.N=0 */ if( kdt->n==0 ) { buf->kcur = 0; result = 0; return result; } /* * Check consistency of request buffer */ nearestneighbor_checkrequestbufferconsistency(kdt, buf, _state); /* * Prepare parameters */ buf->kneeded = 0; if( kdt->normtype!=2 ) { buf->rneeded = r; } else { buf->rneeded = ae_sqr(r, _state); } buf->selfmatch = selfmatch; buf->approxf = (double)(1); buf->kcur = 0; /* * calculate distance from point to current bounding box */ nearestneighbor_kdtreeinitbox(kdt, x, buf, _state); /* * call recursive search * results are returned as heap */ nearestneighbor_kdtreequerynnrec(kdt, buf, 0, _state); result = buf->kcur; /* * pop from heap to generate ordered representation * * last element is not pop'ed because it is already in * its place */ if( orderedbydist ) { j = buf->kcur; for(i=buf->kcur; i>=2; i--) { tagheappopi(&buf->r, &buf->idx, &j, _state); } } return result; } /************************************************************************* Rearranges nodes [I1,I2) using partition in D-th dimension with S as threshold. Returns split position I3: [I1,I3) and [I3,I2) are created as result. This subroutine doesn't create tree structures, just rearranges nodes. *************************************************************************/ static void nearestneighbor_kdtreesplit(kdtree* kdt, ae_int_t i1, ae_int_t i2, ae_int_t d, double s, ae_int_t* i3, ae_state *_state) { ae_int_t i; ae_int_t j; ae_int_t ileft; ae_int_t iright; double v; *i3 = 0; ae_assert(kdt->n>0, "KDTreeSplit: internal error", _state); /* * split XY/Tags in two parts: * * [ILeft,IRight] is non-processed part of XY/Tags * * After cycle is done, we have Ileft=IRight. We deal with * this element separately. * * After this, [I1,ILeft) contains left part, and [ILeft,I2) * contains right part. */ ileft = i1; iright = i2-1; while(ileftxy.ptr.pp_double[ileft][d]<=s ) { /* * XY[ILeft] is on its place. * Advance ILeft. */ ileft = ileft+1; } else { /* * XY[ILeft,..] must be at IRight. * Swap and advance IRight. */ for(i=0; i<=2*kdt->nx+kdt->ny-1; i++) { v = kdt->xy.ptr.pp_double[ileft][i]; kdt->xy.ptr.pp_double[ileft][i] = kdt->xy.ptr.pp_double[iright][i]; kdt->xy.ptr.pp_double[iright][i] = v; } j = kdt->tags.ptr.p_int[ileft]; kdt->tags.ptr.p_int[ileft] = kdt->tags.ptr.p_int[iright]; kdt->tags.ptr.p_int[iright] = j; iright = iright-1; } } if( kdt->xy.ptr.pp_double[ileft][d]<=s ) { ileft = ileft+1; } else { iright = iright-1; } *i3 = ileft; } /************************************************************************* Recursive kd-tree generation subroutine. PARAMETERS KDT tree NodesOffs unused part of Nodes[] which must be filled by tree SplitsOffs unused part of Splits[] I1, I2 points from [I1,I2) are processed NodesOffs[] and SplitsOffs[] must be large enough. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ static void nearestneighbor_kdtreegeneratetreerec(kdtree* kdt, ae_int_t* nodesoffs, ae_int_t* splitsoffs, ae_int_t i1, ae_int_t i2, ae_int_t maxleafsize, ae_state *_state) { ae_int_t n; ae_int_t nx; ae_int_t ny; ae_int_t i; ae_int_t j; ae_int_t oldoffs; ae_int_t i3; ae_int_t cntless; ae_int_t cntgreater; double minv; double maxv; ae_int_t minidx; ae_int_t maxidx; ae_int_t d; double ds; double s; double v; double v0; double v1; ae_assert(kdt->n>0, "KDTreeGenerateTreeRec: internal error", _state); ae_assert(i2>i1, "KDTreeGenerateTreeRec: internal error", _state); /* * Generate leaf if needed */ if( i2-i1<=maxleafsize ) { kdt->nodes.ptr.p_int[*nodesoffs+0] = i2-i1; kdt->nodes.ptr.p_int[*nodesoffs+1] = i1; *nodesoffs = *nodesoffs+2; return; } /* * Load values for easier access */ nx = kdt->nx; ny = kdt->ny; /* * Select dimension to split: * * D is a dimension number * In case bounding box has zero size, we enforce creation of the leaf node. */ d = 0; ds = kdt->innerbuf.curboxmax.ptr.p_double[0]-kdt->innerbuf.curboxmin.ptr.p_double[0]; for(i=1; i<=nx-1; i++) { v = kdt->innerbuf.curboxmax.ptr.p_double[i]-kdt->innerbuf.curboxmin.ptr.p_double[i]; if( v>ds ) { ds = v; d = i; } } if( ae_fp_eq(ds,(double)(0)) ) { kdt->nodes.ptr.p_int[*nodesoffs+0] = i2-i1; kdt->nodes.ptr.p_int[*nodesoffs+1] = i1; *nodesoffs = *nodesoffs+2; return; } /* * Select split position S using sliding midpoint rule, * rearrange points into [I1,I3) and [I3,I2). * * In case all points has same value of D-th component * (MinV=MaxV) we enforce D-th dimension of bounding * box to become exactly zero and repeat tree construction. */ s = kdt->innerbuf.curboxmin.ptr.p_double[d]+0.5*ds; ae_v_move(&kdt->innerbuf.buf.ptr.p_double[0], 1, &kdt->xy.ptr.pp_double[i1][d], kdt->xy.stride, ae_v_len(0,i2-i1-1)); n = i2-i1; cntless = 0; cntgreater = 0; minv = kdt->innerbuf.buf.ptr.p_double[0]; maxv = kdt->innerbuf.buf.ptr.p_double[0]; minidx = i1; maxidx = i1; for(i=0; i<=n-1; i++) { v = kdt->innerbuf.buf.ptr.p_double[i]; if( vmaxv ) { maxv = v; maxidx = i1+i; } if( vs ) { cntgreater = cntgreater+1; } } if( minv==maxv ) { /* * In case all points has same value of D-th component * (MinV=MaxV) we enforce D-th dimension of bounding * box to become exactly zero and repeat tree construction. */ v0 = kdt->innerbuf.curboxmin.ptr.p_double[d]; v1 = kdt->innerbuf.curboxmax.ptr.p_double[d]; kdt->innerbuf.curboxmin.ptr.p_double[d] = minv; kdt->innerbuf.curboxmax.ptr.p_double[d] = maxv; nearestneighbor_kdtreegeneratetreerec(kdt, nodesoffs, splitsoffs, i1, i2, maxleafsize, _state); kdt->innerbuf.curboxmin.ptr.p_double[d] = v0; kdt->innerbuf.curboxmax.ptr.p_double[d] = v1; return; } if( cntless>0&&cntgreater>0 ) { /* * normal midpoint split */ nearestneighbor_kdtreesplit(kdt, i1, i2, d, s, &i3, _state); } else { /* * sliding midpoint */ if( cntless==0 ) { /* * 1. move split to MinV, * 2. place one point to the left bin (move to I1), * others - to the right bin */ s = minv; if( minidx!=i1 ) { for(i=0; i<=2*nx+ny-1; i++) { v = kdt->xy.ptr.pp_double[minidx][i]; kdt->xy.ptr.pp_double[minidx][i] = kdt->xy.ptr.pp_double[i1][i]; kdt->xy.ptr.pp_double[i1][i] = v; } j = kdt->tags.ptr.p_int[minidx]; kdt->tags.ptr.p_int[minidx] = kdt->tags.ptr.p_int[i1]; kdt->tags.ptr.p_int[i1] = j; } i3 = i1+1; } else { /* * 1. move split to MaxV, * 2. place one point to the right bin (move to I2-1), * others - to the left bin */ s = maxv; if( maxidx!=i2-1 ) { for(i=0; i<=2*nx+ny-1; i++) { v = kdt->xy.ptr.pp_double[maxidx][i]; kdt->xy.ptr.pp_double[maxidx][i] = kdt->xy.ptr.pp_double[i2-1][i]; kdt->xy.ptr.pp_double[i2-1][i] = v; } j = kdt->tags.ptr.p_int[maxidx]; kdt->tags.ptr.p_int[maxidx] = kdt->tags.ptr.p_int[i2-1]; kdt->tags.ptr.p_int[i2-1] = j; } i3 = i2-1; } } /* * Generate 'split' node */ kdt->nodes.ptr.p_int[*nodesoffs+0] = 0; kdt->nodes.ptr.p_int[*nodesoffs+1] = d; kdt->nodes.ptr.p_int[*nodesoffs+2] = *splitsoffs; kdt->splits.ptr.p_double[*splitsoffs+0] = s; oldoffs = *nodesoffs; *nodesoffs = *nodesoffs+nearestneighbor_splitnodesize; *splitsoffs = *splitsoffs+1; /* * Recursive generation: * * update CurBox * * call subroutine * * restore CurBox */ kdt->nodes.ptr.p_int[oldoffs+3] = *nodesoffs; v = kdt->innerbuf.curboxmax.ptr.p_double[d]; kdt->innerbuf.curboxmax.ptr.p_double[d] = s; nearestneighbor_kdtreegeneratetreerec(kdt, nodesoffs, splitsoffs, i1, i3, maxleafsize, _state); kdt->innerbuf.curboxmax.ptr.p_double[d] = v; kdt->nodes.ptr.p_int[oldoffs+4] = *nodesoffs; v = kdt->innerbuf.curboxmin.ptr.p_double[d]; kdt->innerbuf.curboxmin.ptr.p_double[d] = s; nearestneighbor_kdtreegeneratetreerec(kdt, nodesoffs, splitsoffs, i3, i2, maxleafsize, _state); kdt->innerbuf.curboxmin.ptr.p_double[d] = v; /* * Zero-fill unused portions of the node (avoid false warnings by Valgrind * about attempt to serialize uninitialized values) */ ae_assert(nearestneighbor_splitnodesize==6, "KDTreeGenerateTreeRec: node size has unexpectedly changed", _state); kdt->nodes.ptr.p_int[oldoffs+5] = 0; } /************************************************************************* Recursive subroutine for NN queries. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ static void nearestneighbor_kdtreequerynnrec(kdtree* kdt, kdtreerequestbuffer* buf, ae_int_t offs, ae_state *_state) { double ptdist; ae_int_t i; ae_int_t j; ae_int_t nx; ae_int_t i1; ae_int_t i2; ae_int_t d; double s; double v; double t1; ae_int_t childbestoffs; ae_int_t childworstoffs; ae_int_t childoffs; double prevdist; ae_bool todive; ae_bool bestisleft; ae_bool updatemin; ae_assert(kdt->n>0, "KDTreeQueryNNRec: internal error", _state); /* * Leaf node. * Process points. */ if( kdt->nodes.ptr.p_int[offs]>0 ) { i1 = kdt->nodes.ptr.p_int[offs+1]; i2 = i1+kdt->nodes.ptr.p_int[offs]; for(i=i1; i<=i2-1; i++) { /* * Calculate distance */ ptdist = (double)(0); nx = kdt->nx; if( kdt->normtype==0 ) { for(j=0; j<=nx-1; j++) { ptdist = ae_maxreal(ptdist, ae_fabs(kdt->xy.ptr.pp_double[i][j]-buf->x.ptr.p_double[j], _state), _state); } } if( kdt->normtype==1 ) { for(j=0; j<=nx-1; j++) { ptdist = ptdist+ae_fabs(kdt->xy.ptr.pp_double[i][j]-buf->x.ptr.p_double[j], _state); } } if( kdt->normtype==2 ) { for(j=0; j<=nx-1; j++) { ptdist = ptdist+ae_sqr(kdt->xy.ptr.pp_double[i][j]-buf->x.ptr.p_double[j], _state); } } /* * Skip points with zero distance if self-matches are turned off */ if( ptdist==0&&!buf->selfmatch ) { continue; } /* * We CAN'T process point if R-criterion isn't satisfied, * i.e. (RNeeded<>0) AND (PtDist>R). */ if( buf->rneeded==0||ptdist<=buf->rneeded ) { /* * R-criterion is satisfied, we must either: * * replace worst point, if (KNeeded<>0) AND (KCur=KNeeded) * (or skip, if worst point is better) * * add point without replacement otherwise */ if( buf->kcurkneeded||buf->kneeded==0 ) { /* * add current point to heap without replacement */ tagheappushi(&buf->r, &buf->idx, &buf->kcur, ptdist, i, _state); } else { /* * New points are added or not, depending on their distance. * If added, they replace element at the top of the heap */ if( ptdistr.ptr.p_double[0] ) { if( buf->kneeded==1 ) { buf->idx.ptr.p_int[0] = i; buf->r.ptr.p_double[0] = ptdist; } else { tagheapreplacetopi(&buf->r, &buf->idx, buf->kneeded, ptdist, i, _state); } } } } } return; } /* * Simple split */ if( kdt->nodes.ptr.p_int[offs]==0 ) { /* * Load: * * D dimension to split * * S split position */ d = kdt->nodes.ptr.p_int[offs+1]; s = kdt->splits.ptr.p_double[kdt->nodes.ptr.p_int[offs+2]]; /* * Calculate: * * ChildBestOffs child box with best chances * * ChildWorstOffs child box with worst chances */ if( buf->x.ptr.p_double[d]<=s ) { childbestoffs = kdt->nodes.ptr.p_int[offs+3]; childworstoffs = kdt->nodes.ptr.p_int[offs+4]; bestisleft = ae_true; } else { childbestoffs = kdt->nodes.ptr.p_int[offs+4]; childworstoffs = kdt->nodes.ptr.p_int[offs+3]; bestisleft = ae_false; } /* * Navigate through childs */ for(i=0; i<=1; i++) { /* * Select child to process: * * ChildOffs current child offset in Nodes[] * * UpdateMin whether minimum or maximum value * of bounding box is changed on update */ if( i==0 ) { childoffs = childbestoffs; updatemin = !bestisleft; } else { updatemin = bestisleft; childoffs = childworstoffs; } /* * Update bounding box and current distance */ if( updatemin ) { prevdist = buf->curdist; t1 = buf->x.ptr.p_double[d]; v = buf->curboxmin.ptr.p_double[d]; if( t1<=s ) { if( kdt->normtype==0 ) { buf->curdist = ae_maxreal(buf->curdist, s-t1, _state); } if( kdt->normtype==1 ) { buf->curdist = buf->curdist-ae_maxreal(v-t1, (double)(0), _state)+s-t1; } if( kdt->normtype==2 ) { buf->curdist = buf->curdist-ae_sqr(ae_maxreal(v-t1, (double)(0), _state), _state)+ae_sqr(s-t1, _state); } } buf->curboxmin.ptr.p_double[d] = s; } else { prevdist = buf->curdist; t1 = buf->x.ptr.p_double[d]; v = buf->curboxmax.ptr.p_double[d]; if( t1>=s ) { if( kdt->normtype==0 ) { buf->curdist = ae_maxreal(buf->curdist, t1-s, _state); } if( kdt->normtype==1 ) { buf->curdist = buf->curdist-ae_maxreal(t1-v, (double)(0), _state)+t1-s; } if( kdt->normtype==2 ) { buf->curdist = buf->curdist-ae_sqr(ae_maxreal(t1-v, (double)(0), _state), _state)+ae_sqr(t1-s, _state); } } buf->curboxmax.ptr.p_double[d] = s; } /* * Decide: to dive into cell or not to dive */ if( buf->rneeded!=0&&buf->curdist>buf->rneeded ) { todive = ae_false; } else { if( buf->kcurkneeded||buf->kneeded==0 ) { /* * KCurcurdist<=buf->r.ptr.p_double[0]*buf->approxf; } } if( todive ) { nearestneighbor_kdtreequerynnrec(kdt, buf, childoffs, _state); } /* * Restore bounding box and distance */ if( updatemin ) { buf->curboxmin.ptr.p_double[d] = v; } else { buf->curboxmax.ptr.p_double[d] = v; } buf->curdist = prevdist; } return; } } /************************************************************************* Recursive subroutine for box queries. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ static void nearestneighbor_kdtreequeryboxrec(kdtree* kdt, kdtreerequestbuffer* buf, ae_int_t offs, ae_state *_state) { ae_bool inbox; ae_int_t nx; ae_int_t i1; ae_int_t i2; ae_int_t i; ae_int_t j; ae_int_t d; double s; double v; ae_assert(kdt->n>0, "KDTreeQueryBoxRec: internal error", _state); nx = kdt->nx; /* * Check that intersection of query box with bounding box is non-empty. * This check is performed once for Offs=0 (tree root). */ if( offs==0 ) { for(j=0; j<=nx-1; j++) { if( buf->boxmin.ptr.p_double[j]>buf->curboxmax.ptr.p_double[j] ) { return; } if( buf->boxmax.ptr.p_double[j]curboxmin.ptr.p_double[j] ) { return; } } } /* * Leaf node. * Process points. */ if( kdt->nodes.ptr.p_int[offs]>0 ) { i1 = kdt->nodes.ptr.p_int[offs+1]; i2 = i1+kdt->nodes.ptr.p_int[offs]; for(i=i1; i<=i2-1; i++) { /* * Check whether point is in box or not */ inbox = ae_true; for(j=0; j<=nx-1; j++) { inbox = inbox&&kdt->xy.ptr.pp_double[i][j]>=buf->boxmin.ptr.p_double[j]; inbox = inbox&&kdt->xy.ptr.pp_double[i][j]<=buf->boxmax.ptr.p_double[j]; } if( !inbox ) { continue; } /* * Add point to unordered list */ buf->r.ptr.p_double[buf->kcur] = 0.0; buf->idx.ptr.p_int[buf->kcur] = i; buf->kcur = buf->kcur+1; } return; } /* * Simple split */ if( kdt->nodes.ptr.p_int[offs]==0 ) { /* * Load: * * D dimension to split * * S split position */ d = kdt->nodes.ptr.p_int[offs+1]; s = kdt->splits.ptr.p_double[kdt->nodes.ptr.p_int[offs+2]]; /* * Check lower split (S is upper bound of new bounding box) */ if( s>=buf->boxmin.ptr.p_double[d] ) { v = buf->curboxmax.ptr.p_double[d]; buf->curboxmax.ptr.p_double[d] = s; nearestneighbor_kdtreequeryboxrec(kdt, buf, kdt->nodes.ptr.p_int[offs+3], _state); buf->curboxmax.ptr.p_double[d] = v; } /* * Check upper split (S is lower bound of new bounding box) */ if( s<=buf->boxmax.ptr.p_double[d] ) { v = buf->curboxmin.ptr.p_double[d]; buf->curboxmin.ptr.p_double[d] = s; nearestneighbor_kdtreequeryboxrec(kdt, buf, kdt->nodes.ptr.p_int[offs+4], _state); buf->curboxmin.ptr.p_double[d] = v; } return; } } /************************************************************************* Copies X[] to Buf.X[] Loads distance from X[] to bounding box. Initializes Buf.CurBox[]. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/ static void nearestneighbor_kdtreeinitbox(kdtree* kdt, /* Real */ ae_vector* x, kdtreerequestbuffer* buf, ae_state *_state) { ae_int_t i; double vx; double vmin; double vmax; ae_assert(kdt->n>0, "KDTreeInitBox: internal error", _state); /* * calculate distance from point to current bounding box */ buf->curdist = (double)(0); if( kdt->normtype==0 ) { for(i=0; i<=kdt->nx-1; i++) { vx = x->ptr.p_double[i]; vmin = kdt->boxmin.ptr.p_double[i]; vmax = kdt->boxmax.ptr.p_double[i]; buf->x.ptr.p_double[i] = vx; buf->curboxmin.ptr.p_double[i] = vmin; buf->curboxmax.ptr.p_double[i] = vmax; if( vxcurdist = ae_maxreal(buf->curdist, vmin-vx, _state); } else { if( vx>vmax ) { buf->curdist = ae_maxreal(buf->curdist, vx-vmax, _state); } } } } if( kdt->normtype==1 ) { for(i=0; i<=kdt->nx-1; i++) { vx = x->ptr.p_double[i]; vmin = kdt->boxmin.ptr.p_double[i]; vmax = kdt->boxmax.ptr.p_double[i]; buf->x.ptr.p_double[i] = vx; buf->curboxmin.ptr.p_double[i] = vmin; buf->curboxmax.ptr.p_double[i] = vmax; if( vxcurdist = buf->curdist+vmin-vx; } else { if( vx>vmax ) { buf->curdist = buf->curdist+vx-vmax; } } } } if( kdt->normtype==2 ) { for(i=0; i<=kdt->nx-1; i++) { vx = x->ptr.p_double[i]; vmin = kdt->boxmin.ptr.p_double[i]; vmax = kdt->boxmax.ptr.p_double[i]; buf->x.ptr.p_double[i] = vx; buf->curboxmin.ptr.p_double[i] = vmin; buf->curboxmax.ptr.p_double[i] = vmax; if( vxcurdist = buf->curdist+ae_sqr(vmin-vx, _state); } else { if( vx>vmax ) { buf->curdist = buf->curdist+ae_sqr(vx-vmax, _state); } } } } } /************************************************************************* This function allocates all dataset-independend array fields of KDTree, i.e. such array fields that their dimensions do not depend on dataset size. This function do not sets KDT.NX or KDT.NY - it just allocates arrays -- ALGLIB -- Copyright 14.03.2011 by Bochkanov Sergey *************************************************************************/ static void nearestneighbor_kdtreeallocdatasetindependent(kdtree* kdt, ae_int_t nx, ae_int_t ny, ae_state *_state) { ae_assert(kdt->n>0, "KDTreeAllocDatasetIndependent: internal error", _state); ae_vector_set_length(&kdt->boxmin, nx, _state); ae_vector_set_length(&kdt->boxmax, nx, _state); } /************************************************************************* This function allocates all dataset-dependent array fields of KDTree, i.e. such array fields that their dimensions depend on dataset size. This function do not sets KDT.N, KDT.NX or KDT.NY - it just allocates arrays. -- ALGLIB -- Copyright 14.03.2011 by Bochkanov Sergey *************************************************************************/ static void nearestneighbor_kdtreeallocdatasetdependent(kdtree* kdt, ae_int_t n, ae_int_t nx, ae_int_t ny, ae_state *_state) { ae_assert(n>0, "KDTreeAllocDatasetDependent: internal error", _state); ae_matrix_set_length(&kdt->xy, n, 2*nx+ny, _state); ae_vector_set_length(&kdt->tags, n, _state); ae_vector_set_length(&kdt->nodes, nearestneighbor_splitnodesize*2*n, _state); ae_vector_set_length(&kdt->splits, 2*n, _state); } /************************************************************************* This function checks consistency of request buffer structure with dimensions of kd-tree object. -- ALGLIB -- Copyright 02.04.2016 by Bochkanov Sergey *************************************************************************/ static void nearestneighbor_checkrequestbufferconsistency(kdtree* kdt, kdtreerequestbuffer* buf, ae_state *_state) { ae_assert(buf->x.cnt>=kdt->nx, "KDTree: dimensions of kdtreerequestbuffer are inconsistent with kdtree structure", _state); ae_assert(buf->idx.cnt>=kdt->n, "KDTree: dimensions of kdtreerequestbuffer are inconsistent with kdtree structure", _state); ae_assert(buf->r.cnt>=kdt->n, "KDTree: dimensions of kdtreerequestbuffer are inconsistent with kdtree structure", _state); ae_assert(buf->buf.cnt>=ae_maxint(kdt->n, kdt->nx, _state), "KDTree: dimensions of kdtreerequestbuffer are inconsistent with kdtree structure", _state); ae_assert(buf->curboxmin.cnt>=kdt->nx, "KDTree: dimensions of kdtreerequestbuffer are inconsistent with kdtree structure", _state); ae_assert(buf->curboxmax.cnt>=kdt->nx, "KDTree: dimensions of kdtreerequestbuffer are inconsistent with kdtree structure", _state); } void _kdtreerequestbuffer_init(void* _p, ae_state *_state, ae_bool make_automatic) { kdtreerequestbuffer *p = (kdtreerequestbuffer*)_p; ae_touch_ptr((void*)p); ae_vector_init(&p->x, 0, DT_REAL, _state, make_automatic); ae_vector_init(&p->boxmin, 0, DT_REAL, _state, make_automatic); ae_vector_init(&p->boxmax, 0, DT_REAL, _state, make_automatic); ae_vector_init(&p->idx, 0, DT_INT, _state, make_automatic); ae_vector_init(&p->r, 0, DT_REAL, _state, make_automatic); ae_vector_init(&p->buf, 0, DT_REAL, _state, make_automatic); ae_vector_init(&p->curboxmin, 0, DT_REAL, _state, make_automatic); ae_vector_init(&p->curboxmax, 0, DT_REAL, _state, make_automatic); } void _kdtreerequestbuffer_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) { kdtreerequestbuffer *dst = (kdtreerequestbuffer*)_dst; kdtreerequestbuffer *src = (kdtreerequestbuffer*)_src; ae_vector_init_copy(&dst->x, &src->x, _state, make_automatic); ae_vector_init_copy(&dst->boxmin, &src->boxmin, _state, make_automatic); ae_vector_init_copy(&dst->boxmax, &src->boxmax, _state, make_automatic); dst->kneeded = src->kneeded; dst->rneeded = src->rneeded; dst->selfmatch = src->selfmatch; dst->approxf = src->approxf; dst->kcur = src->kcur; ae_vector_init_copy(&dst->idx, &src->idx, _state, make_automatic); ae_vector_init_copy(&dst->r, &src->r, _state, make_automatic); ae_vector_init_copy(&dst->buf, &src->buf, _state, make_automatic); ae_vector_init_copy(&dst->curboxmin, &src->curboxmin, _state, make_automatic); ae_vector_init_copy(&dst->curboxmax, &src->curboxmax, _state, make_automatic); dst->curdist = src->curdist; } void _kdtreerequestbuffer_clear(void* _p) { kdtreerequestbuffer *p = (kdtreerequestbuffer*)_p; ae_touch_ptr((void*)p); ae_vector_clear(&p->x); ae_vector_clear(&p->boxmin); ae_vector_clear(&p->boxmax); ae_vector_clear(&p->idx); ae_vector_clear(&p->r); ae_vector_clear(&p->buf); ae_vector_clear(&p->curboxmin); ae_vector_clear(&p->curboxmax); } void _kdtreerequestbuffer_destroy(void* _p) { kdtreerequestbuffer *p = (kdtreerequestbuffer*)_p; ae_touch_ptr((void*)p); ae_vector_destroy(&p->x); ae_vector_destroy(&p->boxmin); ae_vector_destroy(&p->boxmax); ae_vector_destroy(&p->idx); ae_vector_destroy(&p->r); ae_vector_destroy(&p->buf); ae_vector_destroy(&p->curboxmin); ae_vector_destroy(&p->curboxmax); } void _kdtree_init(void* _p, ae_state *_state, ae_bool make_automatic) { kdtree *p = (kdtree*)_p; ae_touch_ptr((void*)p); ae_matrix_init(&p->xy, 0, 0, DT_REAL, _state, make_automatic); ae_vector_init(&p->tags, 0, DT_INT, _state, make_automatic); ae_vector_init(&p->boxmin, 0, DT_REAL, _state, make_automatic); ae_vector_init(&p->boxmax, 0, DT_REAL, _state, make_automatic); ae_vector_init(&p->nodes, 0, DT_INT, _state, make_automatic); ae_vector_init(&p->splits, 0, DT_REAL, _state, make_automatic); _kdtreerequestbuffer_init(&p->innerbuf, _state, make_automatic); } void _kdtree_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) { kdtree *dst = (kdtree*)_dst; kdtree *src = (kdtree*)_src; dst->n = src->n; dst->nx = src->nx; dst->ny = src->ny; dst->normtype = src->normtype; ae_matrix_init_copy(&dst->xy, &src->xy, _state, make_automatic); ae_vector_init_copy(&dst->tags, &src->tags, _state, make_automatic); ae_vector_init_copy(&dst->boxmin, &src->boxmin, _state, make_automatic); ae_vector_init_copy(&dst->boxmax, &src->boxmax, _state, make_automatic); ae_vector_init_copy(&dst->nodes, &src->nodes, _state, make_automatic); ae_vector_init_copy(&dst->splits, &src->splits, _state, make_automatic); _kdtreerequestbuffer_init_copy(&dst->innerbuf, &src->innerbuf, _state, make_automatic); dst->debugcounter = src->debugcounter; } void _kdtree_clear(void* _p) { kdtree *p = (kdtree*)_p; ae_touch_ptr((void*)p); ae_matrix_clear(&p->xy); ae_vector_clear(&p->tags); ae_vector_clear(&p->boxmin); ae_vector_clear(&p->boxmax); ae_vector_clear(&p->nodes); ae_vector_clear(&p->splits); _kdtreerequestbuffer_clear(&p->innerbuf); } void _kdtree_destroy(void* _p) { kdtree *p = (kdtree*)_p; ae_touch_ptr((void*)p); ae_matrix_destroy(&p->xy); ae_vector_destroy(&p->tags); ae_vector_destroy(&p->boxmin); ae_vector_destroy(&p->boxmax); ae_vector_destroy(&p->nodes); ae_vector_destroy(&p->splits); _kdtreerequestbuffer_destroy(&p->innerbuf); } #endif #if defined(AE_COMPILE_HQRND) || !defined(AE_PARTIAL_BUILD) /************************************************************************* HQRNDState initialization with random values which come from standard RNG. -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ void hqrndrandomize(hqrndstate* state, ae_state *_state) { ae_int_t s0; ae_int_t s1; _hqrndstate_clear(state); s0 = ae_randominteger(hqrnd_hqrndm1, _state); s1 = ae_randominteger(hqrnd_hqrndm2, _state); hqrndseed(s0, s1, state, _state); } /************************************************************************* HQRNDState initialization with seed values -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ void hqrndseed(ae_int_t s1, ae_int_t s2, hqrndstate* state, ae_state *_state) { _hqrndstate_clear(state); /* * Protection against negative seeds: * * SEED := -(SEED+1) * * We can use just "-SEED" because there exists such integer number N * that N<0, -N=N<0 too. (This number is equal to 0x800...000). Need * to handle such seed correctly forces us to use a bit complicated * formula. */ if( s1<0 ) { s1 = -(s1+1); } if( s2<0 ) { s2 = -(s2+1); } state->s1 = s1%(hqrnd_hqrndm1-1)+1; state->s2 = s2%(hqrnd_hqrndm2-1)+1; state->magicv = hqrnd_hqrndmagic; } /************************************************************************* This function generates random real number in (0,1), not including interval boundaries State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ double hqrnduniformr(hqrndstate* state, ae_state *_state) { double result; result = (double)(hqrnd_hqrndintegerbase(state, _state)+1)/(double)(hqrnd_hqrndmax+2); return result; } /************************************************************************* This function generates random integer number in [0, N) 1. State structure must be initialized with HQRNDRandomize() or HQRNDSeed() 2. N can be any positive number except for very large numbers: * close to 2^31 on 32-bit systems * close to 2^62 on 64-bit systems An exception will be generated if N is too large. -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ ae_int_t hqrnduniformi(hqrndstate* state, ae_int_t n, ae_state *_state) { ae_int_t maxcnt; ae_int_t mx; ae_int_t a; ae_int_t b; ae_int_t result; ae_assert(n>0, "HQRNDUniformI: N<=0!", _state); maxcnt = hqrnd_hqrndmax+1; /* * Two branches: one for N<=MaxCnt, another for N>MaxCnt. */ if( n>maxcnt ) { /* * N>=MaxCnt. * * We have two options here: * a) N is exactly divisible by MaxCnt * b) N is not divisible by MaxCnt * * In both cases we reduce problem on interval spanning [0,N) * to several subproblems on intervals spanning [0,MaxCnt). */ if( n%maxcnt==0 ) { /* * N is exactly divisible by MaxCnt. * * [0,N) range is dividided into N/MaxCnt bins, * each of them having length equal to MaxCnt. * * We generate: * * random bin number B * * random offset within bin A * Both random numbers are generated by recursively * calling HQRNDUniformI(). * * Result is equal to A+MaxCnt*B. */ ae_assert(n/maxcnt<=maxcnt, "HQRNDUniformI: N is too large", _state); a = hqrnduniformi(state, maxcnt, _state); b = hqrnduniformi(state, n/maxcnt, _state); result = a+maxcnt*b; } else { /* * N is NOT exactly divisible by MaxCnt. * * [0,N) range is dividided into Ceil(N/MaxCnt) bins, * each of them having length equal to MaxCnt. * * We generate: * * random bin number B in [0, Ceil(N/MaxCnt)-1] * * random offset within bin A * * if both of what is below is true * 1) bin number B is that of the last bin * 2) A >= N mod MaxCnt * then we repeat generation of A/B. * This stage is essential in order to avoid bias in the result. * * otherwise, we return A*MaxCnt+N */ ae_assert(n/maxcnt+1<=maxcnt, "HQRNDUniformI: N is too large", _state); result = -1; do { a = hqrnduniformi(state, maxcnt, _state); b = hqrnduniformi(state, n/maxcnt+1, _state); if( b==n/maxcnt&&a>=n%maxcnt ) { continue; } result = a+maxcnt*b; } while(result<0); } } else { /* * N<=MaxCnt * * Code below is a bit complicated because we can not simply * return "HQRNDIntegerBase() mod N" - it will be skewed for * large N's in [0.1*HQRNDMax...HQRNDMax]. */ mx = maxcnt-maxcnt%n; do { result = hqrnd_hqrndintegerbase(state, _state); } while(result>=mx); result = result%n; } return result; } /************************************************************************* Random number generator: normal numbers This function generates one random number from normal distribution. Its performance is equal to that of HQRNDNormal2() State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ double hqrndnormal(hqrndstate* state, ae_state *_state) { double v1; double v2; double result; hqrndnormal2(state, &v1, &v2, _state); result = v1; return result; } /************************************************************************* Random number generator: random X and Y such that X^2+Y^2=1 State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ void hqrndunit2(hqrndstate* state, double* x, double* y, ae_state *_state) { double v; double mx; double mn; *x = 0; *y = 0; do { hqrndnormal2(state, x, y, _state); } while(!(ae_fp_neq(*x,(double)(0))||ae_fp_neq(*y,(double)(0)))); mx = ae_maxreal(ae_fabs(*x, _state), ae_fabs(*y, _state), _state); mn = ae_minreal(ae_fabs(*x, _state), ae_fabs(*y, _state), _state); v = mx*ae_sqrt(1+ae_sqr(mn/mx, _state), _state); *x = *x/v; *y = *y/v; } /************************************************************************* Random number generator: normal numbers This function generates two independent random numbers from normal distribution. Its performance is equal to that of HQRNDNormal() State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ void hqrndnormal2(hqrndstate* state, double* x1, double* x2, ae_state *_state) { double u; double v; double s; *x1 = 0; *x2 = 0; for(;;) { u = 2*hqrnduniformr(state, _state)-1; v = 2*hqrnduniformr(state, _state)-1; s = ae_sqr(u, _state)+ae_sqr(v, _state); if( ae_fp_greater(s,(double)(0))&&ae_fp_less(s,(double)(1)) ) { /* * two Sqrt's instead of one to * avoid overflow when S is too small */ s = ae_sqrt(-2*ae_log(s, _state), _state)/ae_sqrt(s, _state); *x1 = u*s; *x2 = v*s; return; } } } /************************************************************************* Random number generator: exponential distribution State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 11.08.2007 by Bochkanov Sergey *************************************************************************/ double hqrndexponential(hqrndstate* state, double lambdav, ae_state *_state) { double result; ae_assert(ae_fp_greater(lambdav,(double)(0)), "HQRNDExponential: LambdaV<=0!", _state); result = -ae_log(hqrnduniformr(state, _state), _state)/lambdav; return result; } /************************************************************************* This function generates random number from discrete distribution given by finite sample X. INPUT PARAMETERS State - high quality random number generator, must be initialized with HQRNDRandomize() or HQRNDSeed(). X - finite sample N - number of elements to use, N>=1 RESULT this function returns one of the X[i] for random i=0..N-1 -- ALGLIB -- Copyright 08.11.2011 by Bochkanov Sergey *************************************************************************/ double hqrnddiscrete(hqrndstate* state, /* Real */ ae_vector* x, ae_int_t n, ae_state *_state) { double result; ae_assert(n>0, "HQRNDDiscrete: N<=0", _state); ae_assert(n<=x->cnt, "HQRNDDiscrete: Length(X)ptr.p_double[hqrnduniformi(state, n, _state)]; return result; } /************************************************************************* This function generates random number from continuous distribution given by finite sample X. INPUT PARAMETERS State - high quality random number generator, must be initialized with HQRNDRandomize() or HQRNDSeed(). X - finite sample, array[N] (can be larger, in this case only leading N elements are used). THIS ARRAY MUST BE SORTED BY ASCENDING. N - number of elements to use, N>=1 RESULT this function returns random number from continuous distribution which tries to approximate X as mush as possible. min(X)<=Result<=max(X). -- ALGLIB -- Copyright 08.11.2011 by Bochkanov Sergey *************************************************************************/ double hqrndcontinuous(hqrndstate* state, /* Real */ ae_vector* x, ae_int_t n, ae_state *_state) { double mx; double mn; ae_int_t i; double result; ae_assert(n>0, "HQRNDContinuous: N<=0", _state); ae_assert(n<=x->cnt, "HQRNDContinuous: Length(X)ptr.p_double[0]; return result; } i = hqrnduniformi(state, n-1, _state); mn = x->ptr.p_double[i]; mx = x->ptr.p_double[i+1]; ae_assert(ae_fp_greater_eq(mx,mn), "HQRNDDiscrete: X is not sorted by ascending", _state); if( ae_fp_neq(mx,mn) ) { result = (mx-mn)*hqrnduniformr(state, _state)+mn; } else { result = mn; } return result; } /************************************************************************* This function returns random integer in [0,HQRNDMax] L'Ecuyer, Efficient and portable combined random number generators *************************************************************************/ static ae_int_t hqrnd_hqrndintegerbase(hqrndstate* state, ae_state *_state) { ae_int_t k; ae_int_t result; ae_assert(state->magicv==hqrnd_hqrndmagic, "HQRNDIntegerBase: State is not correctly initialized!", _state); k = state->s1/53668; state->s1 = 40014*(state->s1-k*53668)-k*12211; if( state->s1<0 ) { state->s1 = state->s1+2147483563; } k = state->s2/52774; state->s2 = 40692*(state->s2-k*52774)-k*3791; if( state->s2<0 ) { state->s2 = state->s2+2147483399; } /* * Result */ result = state->s1-state->s2; if( result<1 ) { result = result+2147483562; } result = result-1; return result; } void _hqrndstate_init(void* _p, ae_state *_state, ae_bool make_automatic) { hqrndstate *p = (hqrndstate*)_p; ae_touch_ptr((void*)p); } void _hqrndstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) { hqrndstate *dst = (hqrndstate*)_dst; hqrndstate *src = (hqrndstate*)_src; dst->s1 = src->s1; dst->s2 = src->s2; dst->magicv = src->magicv; } void _hqrndstate_clear(void* _p) { hqrndstate *p = (hqrndstate*)_p; ae_touch_ptr((void*)p); } void _hqrndstate_destroy(void* _p) { hqrndstate *p = (hqrndstate*)_p; ae_touch_ptr((void*)p); } #endif #if defined(AE_COMPILE_XDEBUG) || !defined(AE_PARTIAL_BUILD) /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Creates and returns XDebugRecord1 structure: * integer and complex fields of Rec1 are set to 1 and 1+i correspondingly * array field of Rec1 is set to [2,3] -- ALGLIB -- Copyright 27.05.2014 by Bochkanov Sergey *************************************************************************/ void xdebuginitrecord1(xdebugrecord1* rec1, ae_state *_state) { _xdebugrecord1_clear(rec1); rec1->i = 1; rec1->c.x = (double)(1); rec1->c.y = (double)(1); ae_vector_set_length(&rec1->a, 2, _state); rec1->a.ptr.p_double[0] = (double)(2); rec1->a.ptr.p_double[1] = (double)(3); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Counts number of True values in the boolean 1D array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ ae_int_t xdebugb1count(/* Boolean */ ae_vector* a, ae_state *_state) { ae_int_t i; ae_int_t result; result = 0; for(i=0; i<=a->cnt-1; i++) { if( a->ptr.p_bool[i] ) { result = result+1; } } return result; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by NOT(a[i]). Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb1not(/* Boolean */ ae_vector* a, ae_state *_state) { ae_int_t i; for(i=0; i<=a->cnt-1; i++) { a->ptr.p_bool[i] = !a->ptr.p_bool[i]; } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Appends copy of array to itself. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb1appendcopy(/* Boolean */ ae_vector* a, ae_state *_state) { ae_frame _frame_block; ae_int_t i; ae_vector b; ae_frame_make(_state, &_frame_block); memset(&b, 0, sizeof(b)); ae_vector_init(&b, 0, DT_BOOL, _state, ae_true); ae_vector_set_length(&b, a->cnt, _state); for(i=0; i<=b.cnt-1; i++) { b.ptr.p_bool[i] = a->ptr.p_bool[i]; } ae_vector_set_length(a, 2*b.cnt, _state); for(i=0; i<=a->cnt-1; i++) { a->ptr.p_bool[i] = b.ptr.p_bool[i%b.cnt]; } ae_frame_leave(_state); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate N-element array with even-numbered elements set to True. Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb1outeven(ae_int_t n, /* Boolean */ ae_vector* a, ae_state *_state) { ae_int_t i; ae_vector_clear(a); ae_vector_set_length(a, n, _state); for(i=0; i<=a->cnt-1; i++) { a->ptr.p_bool[i] = i%2==0; } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ ae_int_t xdebugi1sum(/* Integer */ ae_vector* a, ae_state *_state) { ae_int_t i; ae_int_t result; result = 0; for(i=0; i<=a->cnt-1; i++) { result = result+a->ptr.p_int[i]; } return result; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -A[I] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi1neg(/* Integer */ ae_vector* a, ae_state *_state) { ae_int_t i; for(i=0; i<=a->cnt-1; i++) { a->ptr.p_int[i] = -a->ptr.p_int[i]; } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Appends copy of array to itself. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi1appendcopy(/* Integer */ ae_vector* a, ae_state *_state) { ae_frame _frame_block; ae_int_t i; ae_vector b; ae_frame_make(_state, &_frame_block); memset(&b, 0, sizeof(b)); ae_vector_init(&b, 0, DT_INT, _state, ae_true); ae_vector_set_length(&b, a->cnt, _state); for(i=0; i<=b.cnt-1; i++) { b.ptr.p_int[i] = a->ptr.p_int[i]; } ae_vector_set_length(a, 2*b.cnt, _state); for(i=0; i<=a->cnt-1; i++) { a->ptr.p_int[i] = b.ptr.p_int[i%b.cnt]; } ae_frame_leave(_state); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate N-element array with even-numbered A[I] set to I, and odd-numbered ones set to 0. Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi1outeven(ae_int_t n, /* Integer */ ae_vector* a, ae_state *_state) { ae_int_t i; ae_vector_clear(a); ae_vector_set_length(a, n, _state); for(i=0; i<=a->cnt-1; i++) { if( i%2==0 ) { a->ptr.p_int[i] = i; } else { a->ptr.p_int[i] = 0; } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ double xdebugr1sum(/* Real */ ae_vector* a, ae_state *_state) { ae_int_t i; double result; result = (double)(0); for(i=0; i<=a->cnt-1; i++) { result = result+a->ptr.p_double[i]; } return result; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -A[I] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr1neg(/* Real */ ae_vector* a, ae_state *_state) { ae_int_t i; for(i=0; i<=a->cnt-1; i++) { a->ptr.p_double[i] = -a->ptr.p_double[i]; } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Appends copy of array to itself. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr1appendcopy(/* Real */ ae_vector* a, ae_state *_state) { ae_frame _frame_block; ae_int_t i; ae_vector b; ae_frame_make(_state, &_frame_block); memset(&b, 0, sizeof(b)); ae_vector_init(&b, 0, DT_REAL, _state, ae_true); ae_vector_set_length(&b, a->cnt, _state); for(i=0; i<=b.cnt-1; i++) { b.ptr.p_double[i] = a->ptr.p_double[i]; } ae_vector_set_length(a, 2*b.cnt, _state); for(i=0; i<=a->cnt-1; i++) { a->ptr.p_double[i] = b.ptr.p_double[i%b.cnt]; } ae_frame_leave(_state); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate N-element array with even-numbered A[I] set to I*0.25, and odd-numbered ones are set to 0. Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr1outeven(ae_int_t n, /* Real */ ae_vector* a, ae_state *_state) { ae_int_t i; ae_vector_clear(a); ae_vector_set_length(a, n, _state); for(i=0; i<=a->cnt-1; i++) { if( i%2==0 ) { a->ptr.p_double[i] = i*0.25; } else { a->ptr.p_double[i] = (double)(0); } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ ae_complex xdebugc1sum(/* Complex */ ae_vector* a, ae_state *_state) { ae_int_t i; ae_complex result; result = ae_complex_from_i(0); for(i=0; i<=a->cnt-1; i++) { result = ae_c_add(result,a->ptr.p_complex[i]); } return result; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -A[I] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc1neg(/* Complex */ ae_vector* a, ae_state *_state) { ae_int_t i; for(i=0; i<=a->cnt-1; i++) { a->ptr.p_complex[i] = ae_c_neg(a->ptr.p_complex[i]); } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Appends copy of array to itself. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc1appendcopy(/* Complex */ ae_vector* a, ae_state *_state) { ae_frame _frame_block; ae_int_t i; ae_vector b; ae_frame_make(_state, &_frame_block); memset(&b, 0, sizeof(b)); ae_vector_init(&b, 0, DT_COMPLEX, _state, ae_true); ae_vector_set_length(&b, a->cnt, _state); for(i=0; i<=b.cnt-1; i++) { b.ptr.p_complex[i] = a->ptr.p_complex[i]; } ae_vector_set_length(a, 2*b.cnt, _state); for(i=0; i<=a->cnt-1; i++) { a->ptr.p_complex[i] = b.ptr.p_complex[i%b.cnt]; } ae_frame_leave(_state); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate N-element array with even-numbered A[K] set to (x,y) = (K*0.25, K*0.125) and odd-numbered ones are set to 0. Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc1outeven(ae_int_t n, /* Complex */ ae_vector* a, ae_state *_state) { ae_int_t i; ae_vector_clear(a); ae_vector_set_length(a, n, _state); for(i=0; i<=a->cnt-1; i++) { if( i%2==0 ) { a->ptr.p_complex[i].x = i*0.250; a->ptr.p_complex[i].y = i*0.125; } else { a->ptr.p_complex[i] = ae_complex_from_i(0); } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Counts number of True values in the boolean 2D array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ ae_int_t xdebugb2count(/* Boolean */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; ae_int_t result; result = 0; for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { if( a->ptr.pp_bool[i][j] ) { result = result+1; } } } return result; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by NOT(a[i]). Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb2not(/* Boolean */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { a->ptr.pp_bool[i][j] = !a->ptr.pp_bool[i][j]; } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Transposes array. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb2transpose(/* Boolean */ ae_matrix* a, ae_state *_state) { ae_frame _frame_block; ae_int_t i; ae_int_t j; ae_matrix b; ae_frame_make(_state, &_frame_block); memset(&b, 0, sizeof(b)); ae_matrix_init(&b, 0, 0, DT_BOOL, _state, ae_true); ae_matrix_set_length(&b, a->rows, a->cols, _state); for(i=0; i<=b.rows-1; i++) { for(j=0; j<=b.cols-1; j++) { b.ptr.pp_bool[i][j] = a->ptr.pp_bool[i][j]; } } ae_matrix_set_length(a, b.cols, b.rows, _state); for(i=0; i<=b.rows-1; i++) { for(j=0; j<=b.cols-1; j++) { a->ptr.pp_bool[j][i] = b.ptr.pp_bool[i][j]; } } ae_frame_leave(_state); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate MxN matrix with elements set to "Sin(3*I+5*J)>0" Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugb2outsin(ae_int_t m, ae_int_t n, /* Boolean */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; ae_matrix_clear(a); ae_matrix_set_length(a, m, n, _state); for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { a->ptr.pp_bool[i][j] = ae_fp_greater(ae_sin((double)(3*i+5*j), _state),(double)(0)); } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ ae_int_t xdebugi2sum(/* Integer */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; ae_int_t result; result = 0; for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { result = result+a->ptr.pp_int[i][j]; } } return result; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -a[i,j] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi2neg(/* Integer */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { a->ptr.pp_int[i][j] = -a->ptr.pp_int[i][j]; } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Transposes array. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi2transpose(/* Integer */ ae_matrix* a, ae_state *_state) { ae_frame _frame_block; ae_int_t i; ae_int_t j; ae_matrix b; ae_frame_make(_state, &_frame_block); memset(&b, 0, sizeof(b)); ae_matrix_init(&b, 0, 0, DT_INT, _state, ae_true); ae_matrix_set_length(&b, a->rows, a->cols, _state); for(i=0; i<=b.rows-1; i++) { for(j=0; j<=b.cols-1; j++) { b.ptr.pp_int[i][j] = a->ptr.pp_int[i][j]; } } ae_matrix_set_length(a, b.cols, b.rows, _state); for(i=0; i<=b.rows-1; i++) { for(j=0; j<=b.cols-1; j++) { a->ptr.pp_int[j][i] = b.ptr.pp_int[i][j]; } } ae_frame_leave(_state); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate MxN matrix with elements set to "Sign(Sin(3*I+5*J))" Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugi2outsin(ae_int_t m, ae_int_t n, /* Integer */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; ae_matrix_clear(a); ae_matrix_set_length(a, m, n, _state); for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { a->ptr.pp_int[i][j] = ae_sign(ae_sin((double)(3*i+5*j), _state), _state); } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ double xdebugr2sum(/* Real */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; double result; result = (double)(0); for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { result = result+a->ptr.pp_double[i][j]; } } return result; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -a[i,j] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr2neg(/* Real */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { a->ptr.pp_double[i][j] = -a->ptr.pp_double[i][j]; } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Transposes array. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr2transpose(/* Real */ ae_matrix* a, ae_state *_state) { ae_frame _frame_block; ae_int_t i; ae_int_t j; ae_matrix b; ae_frame_make(_state, &_frame_block); memset(&b, 0, sizeof(b)); ae_matrix_init(&b, 0, 0, DT_REAL, _state, ae_true); ae_matrix_set_length(&b, a->rows, a->cols, _state); for(i=0; i<=b.rows-1; i++) { for(j=0; j<=b.cols-1; j++) { b.ptr.pp_double[i][j] = a->ptr.pp_double[i][j]; } } ae_matrix_set_length(a, b.cols, b.rows, _state); for(i=0; i<=b.rows-1; i++) { for(j=0; j<=b.cols-1; j++) { a->ptr.pp_double[j][i] = b.ptr.pp_double[i][j]; } } ae_frame_leave(_state); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate MxN matrix with elements set to "Sin(3*I+5*J)" Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugr2outsin(ae_int_t m, ae_int_t n, /* Real */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; ae_matrix_clear(a); ae_matrix_set_length(a, m, n, _state); for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { a->ptr.pp_double[i][j] = ae_sin((double)(3*i+5*j), _state); } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of elements in the array. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ ae_complex xdebugc2sum(/* Complex */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; ae_complex result; result = ae_complex_from_i(0); for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { result = ae_c_add(result,a->ptr.pp_complex[i][j]); } } return result; } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Replace all values in array by -a[i,j] Array is passed using "shared" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc2neg(/* Complex */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { a->ptr.pp_complex[i][j] = ae_c_neg(a->ptr.pp_complex[i][j]); } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Transposes array. Array is passed using "var" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc2transpose(/* Complex */ ae_matrix* a, ae_state *_state) { ae_frame _frame_block; ae_int_t i; ae_int_t j; ae_matrix b; ae_frame_make(_state, &_frame_block); memset(&b, 0, sizeof(b)); ae_matrix_init(&b, 0, 0, DT_COMPLEX, _state, ae_true); ae_matrix_set_length(&b, a->rows, a->cols, _state); for(i=0; i<=b.rows-1; i++) { for(j=0; j<=b.cols-1; j++) { b.ptr.pp_complex[i][j] = a->ptr.pp_complex[i][j]; } } ae_matrix_set_length(a, b.cols, b.rows, _state); for(i=0; i<=b.rows-1; i++) { for(j=0; j<=b.cols-1; j++) { a->ptr.pp_complex[j][i] = b.ptr.pp_complex[i][j]; } } ae_frame_leave(_state); } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Generate MxN matrix with elements set to "Sin(3*I+5*J),Cos(3*I+5*J)" Array is passed using "out" convention. -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ void xdebugc2outsincos(ae_int_t m, ae_int_t n, /* Complex */ ae_matrix* a, ae_state *_state) { ae_int_t i; ae_int_t j; ae_matrix_clear(a); ae_matrix_set_length(a, m, n, _state); for(i=0; i<=a->rows-1; i++) { for(j=0; j<=a->cols-1; j++) { a->ptr.pp_complex[i][j].x = ae_sin((double)(3*i+5*j), _state); a->ptr.pp_complex[i][j].y = ae_cos((double)(3*i+5*j), _state); } } } /************************************************************************* This is debug function intended for testing ALGLIB interface generator. Never use it in any real life project. Returns sum of a[i,j]*(1+b[i,j]) such that c[i,j] is True -- ALGLIB -- Copyright 11.10.2013 by Bochkanov Sergey *************************************************************************/ double xdebugmaskedbiasedproductsum(ae_int_t m, ae_int_t n, /* Real */ ae_matrix* a, /* Real */ ae_matrix* b, /* Boolean */ ae_matrix* c, ae_state *_state) { ae_int_t i; ae_int_t j; double result; ae_assert(m>=a->rows, "Assertion failed", _state); ae_assert(m>=b->rows, "Assertion failed", _state); ae_assert(m>=c->rows, "Assertion failed", _state); ae_assert(n>=a->cols, "Assertion failed", _state); ae_assert(n>=b->cols, "Assertion failed", _state); ae_assert(n>=c->cols, "Assertion failed", _state); result = 0.0; for(i=0; i<=m-1; i++) { for(j=0; j<=n-1; j++) { if( c->ptr.pp_bool[i][j] ) { result = result+a->ptr.pp_double[i][j]*(1+b->ptr.pp_double[i][j]); } } } return result; } void _xdebugrecord1_init(void* _p, ae_state *_state, ae_bool make_automatic) { xdebugrecord1 *p = (xdebugrecord1*)_p; ae_touch_ptr((void*)p); ae_vector_init(&p->a, 0, DT_REAL, _state, make_automatic); } void _xdebugrecord1_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) { xdebugrecord1 *dst = (xdebugrecord1*)_dst; xdebugrecord1 *src = (xdebugrecord1*)_src; dst->i = src->i; dst->c = src->c; ae_vector_init_copy(&dst->a, &src->a, _state, make_automatic); } void _xdebugrecord1_clear(void* _p) { xdebugrecord1 *p = (xdebugrecord1*)_p; ae_touch_ptr((void*)p); ae_vector_clear(&p->a); } void _xdebugrecord1_destroy(void* _p) { xdebugrecord1 *p = (xdebugrecord1*)_p; ae_touch_ptr((void*)p); ae_vector_destroy(&p->a); } #endif }