1 Introduction
1.1 What is ALGLIB
1.2 ALGLIB license
1.3 Documentation license
1.4 Reference Manual and User Guide
1.5 Acknowledgements
2 ALGLIB structure
2.1 Packages
2.2 Subpackages
2.3 Open Source and Commercial versions
3 Compatibility
3.1 CPU
3.2 OS
3.3 Compiler
3.4 Optimization settings
4 Compiling ALGLIB
4.1 Adding to your project
4.2 Configuring for your compiler
4.3 Utilizing SIMD
4.3.1 Overview
4.3.2 Achieving best performance
4.3.3 Achieving best portability
4.3.4 Disabling SIMD instruction sets at compile time
4.4 Utilizing SMP
4.5 Examples (free and commercial editions)
4.5.1 Introduction
4.5.2 Compiling under Windows
4.5.3 Compiling under Linux
5 Using ALGLIB
5.1 Thread-safety
5.2 Global definitions
5.3 Datatypes
5.4 Constants
5.5 Functions
5.6 Working with vectors and matrices
5.7 Using functions: 'expert' and 'friendly' interfaces
5.8 Handling errors
5.9 Working with Level 1 BLAS functions
5.10 Reading data from CSV files
6 Working with commercial version
6.1 Benefits of commercial version
6.2 Working with SIMD support (Intel/AMD users)
6.3 Using multithreading
6.3.1 General information
6.3.2 Compiling ALGLIB in the multithreaded mode
6.3.3 Two kinds of parallelism
6.3.4 Activating parallelism
6.3.5 Controlling cores count
6.3.6 More on parallel callbacks
6.3.7 SMT/hyper-threading issues
6.4 Linking with precompiled performance backends
6.4.1 Introduction
6.4.2 Using precompiled performance backends
6.4.3 Performance backend: mklmini
6.4.4 Performance backend: mklfull
6.5 Linking with performance backends installed on your system
6.5.1 Using your own installation of Intel MKL
7 Advanced topics
7.1 Using Red Zones to find memory access violations
7.2 Replacing stdlib rand() as an entropy source with OpenSSL implementation
7.3 Exception-free mode
7.4 Partial compilation
7.5 Testing ALGLIB
8 ALGLIB packages and subpackages
8.1 AlglibMisc package
8.2 DataAnalysis package
8.3 DiffEquations package
8.4 FastTransforms package
8.5 Integration package
8.6 Interpolation package
8.7 LinAlg package
8.8 MINLP package
8.9 Optimization package
8.10 Solvers package
8.11 SpecialFunctions package
8.12 Statistics package
ALGLIB is a cross-platform numerical analysis library. It supports several programming languages (C++, C#, Java, Delphi, VB.NET, Python) and several operating systems (Windows, *nix family).
ALGLIB features include:
ALGLIB Project (the company behind ALGLIB) delivers to you several editions of ALGLIB:
Free Edition is a serial version without multithreading support and with a limited set of SIMD optimizations. Commercial Edition is a heavily optimized version of ALGLIB. It supports multithreading, it is extensively optimized, and (on Intel platforms) - our commercial users may enjoy precompiled performance backends (based on Intel MKL) that accelerate low-level tasks like basic dense and sparse linear algebra. We obtained a license from Intel corp., which allows us to integrate Intel MKL into ALGLIB, so you don't have to get a separate license from Intel.
ALGLIB Free Edition is distributed under license which favors non-commercial usage, but is not well suited for commercial applications:
ALGLIB Commercial Edition is distributed under license which is friendly to commercial users. A copy of the commercial license can be found at http://www.alglib.net/commercial.php.
This reference manual is licensed under BSD-like documentation license:
Copyright 1994-2017 Sergey Bochkanov, ALGLIB Project. All rights reserved.
Redistribution and use of this document (ALGLIB Reference Manual) with or without modification, are permitted provided that such redistributions will retain the above copyright notice, this condition and the following disclaimer as the first (or last) lines of this file.
THIS DOCUMENTATION IS PROVIDED BY THE ALGLIB PROJECT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ALGLIB PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ALGLIB Project provides two sources of information: ALGLIB Reference Manual (this document) and ALGLIB User Guide.
ALGLIB Reference Manual contains full description of all publicly accessible ALGLIB units accompanied with examples.
Reference Manual is focused on the source code: it documents units, functions, structures and so on.
If you want to know what unit YYY can do or what subroutines unit ZZZ contains, the Reference Manual is a place to go.
Free software needs free documentation - that's why the ALGLIB Reference Manual is licensed under BSD-like documentation license.
Additionally to the Reference Manual we provide you User Guide. User Guide is focused on more general questions: how fast ALGLIB is? how reliable is it? what are the strong and weak sides of the algorithms used? We aim to make ALGLIB User Guide an important source of information both about ALGLIB and numerical analysis algorithms in general. We want it to be a book about algorithms, not just software documentation. And we want it to be unique - that's why the ALGLIB User Guide is distributed under a less-permissive personal-use-only license.
ALGLIB was not possible without contribution of the following open source projects:
We also want to thank developers of the Intel's evelopment center for their help during MKL integration.
ALGLIB is a C++ interface to the computational core written in C. Both C library and C++ wrapper are automatically generated by code generation tools developed within ALGLIB project. ALGLIB includes 11 packages and 5 support units:
The packages are:
The support units are:
One package may rely on other ones, but we have tried to reduce number of dependencies.
Every package relies on ap.cpp and many packages rely on alglibinternal.cpp and kernels.
But many packages require only these five to work, and many other packages need significantly less than 13 packages.
For example, statistics.cpp requires five files mentioned above and only one additional package - specialfunctions.cpp.
There is one more concept to learn - subpackages.
If you look at the list of ALGLIB packages, you will see that each package includes several subpackages.
For example, linalg.cpp includes trfac, svd, evd and other subpackages.
These subpackages do no exist as separate files, namespaces or other entities.
They are just subsets of one large unit which provide significantly different functionality.
They have separate documentation sections, but if you want to use svd subpackage, you have to include linalg.h, not svd.h.
ALGLIB comes in two versions - open source (GPL-licensed) and commercial (closed source) one. Both versions have same functionality, i.e. may solve same set of problems. However, commercial version differs from the open source one in following respects:
This documentation applies to both versions of ALGLIB. Detailed description of the commercial version can be found below.
ALGLIB is compatible with any CPU which:
All mainstream CPU's (in particular, x86, x86_64, ARM, RISC-V) satisfy these requirements.
As for Intel architecture, ALGLIB works with both FPU-based and SIMD-based implementations of the floating point math.
ALGLIB for C++ (both open source and commercial versions) can be compiled in OS-agnostic mode (no OS-specific preprocessor definitions), when it is compatible with any OS which supports C++98 standard library. In particular, it will work under any POSIX-compatible OS and under Windows.
If you want to use multithreaded capabilities of the commercial version of ALGLIB,
you should compile it in OS-specific mode by #defining either AE_OS=AE_WINDOWS,
AE_OS=AE_LINUX or AE_OS=AE_POSIX at compile time, depending on OS being used.
Former corresponds to any OS from the Windows family (from most recent Windows versions and downb to 32/64-bit Windows XP),
while latter two means almost any LINUX edition or generic POSIX-compatible OS.
Specifying AE_OS=AE_LINUX allows ALGLIB to use Linux-specific performance-related OS extensions,
while AE_OS=AE_POSIX allows ALGLIB to run on any POSIX-compatible OS.
It applies only to commercial version of ALGLIB.
Open source version is always OS-agnostic, even in the presence of OS-specific definitions.
ALGLIB is compatible with any C++ compiler which:
x/0 will return INF.
But at least we must be able to compare double precision value with infinity or NAN without raising exception.All modern mainstream compilers (MSVC, GCC, Clang, ICC) satisfy these requirements. Most specialized compilers for DSPs also satisfy them.
ALGLIB is compatible with any kind of optimizing compiler as long as:
Generally, all kinds of optimization that were marked by compiler vendor as "safe" are possible. For example, ALGLIB can be compiled:
From the other side, following "unsafe" optimizations will break ALGLIB:
Adding ALGLIB to your project is easy - just pick packages you need and... add them to your project! Under most used compilers (GCC, MSVC) it will work without any additional settings. In other cases you will need to define several preprocessor definitions (this topic will be detailed below), but everything will still be simple.
By "adding to your project" we mean that you should a) compile .cpp files with the rest of your project, and b) include .h files you need. Do not include .cpp files - these files must be compiled separately, not as part of some larger source file. The only files you should include are .h files, stored in the /src folder of the ALGLIB distribution.
As you see, ALGLIB has no project files or makefiles. Why? There are several reasons:
In any case, compiling ALGLIB is so simple that even without project file you can do it in several minutes.
If you use modern versions of MSVC, GCC, Clang or ICC, you don't need to configure ALGLIB at all. But if you use outdated versions of these compilers (or something else), then you may need to tune definitions of several data types:
ALGLIB tries to autodetect your compiler and to define these types in compiler-specific manner:
ae_int32_t is defined as int, because this type is 32 bits wide in all modern compilers.ae_int64_t is defined as _int64 (MSVC) or as signed long long (GCC).ae_uint64_t is defined as unsigned _int64 (MSVC) or as unsigned long long (GCC).ae_int_t is defined as ptrdiff_t.In most cases, it is enough. But if anything goes wrong, you have several options:
stdint.h, you can define AE_HAVE_STDINT conditional symbolAE_INT32_T and/or AE_INT64_T and/or AE_UINT64_T and/or AE_INT_T symbols.
Just assign datatype name to them, and ALGLIB will automatically use your definition.
You may define all or just one/two types (those which are not detected automatically).
ALGLIB has two-layered structure: some set of basic performance-critical primitives is implemented using optimized code
(kernels_sse2.cpp, kernels_avx2.cpp and kernels_fma.cpp),
and the rest of the library is built on top of these primitives.
By default, ALGLIB uses generic C code to implement these primitives (matrix multiplication, decompositions, etc.).
This code works on any CPU architecture that has IEEE-754 floating point support (including exotic DSPs).
However, much better performance may be achieved by utilizing SIMD-capable high-performance kernels included into the ALGLIB. These kernels are implemented using C/C++ SIMD intrinsics (as opposed to the assembly language) and provide good performance combined with benefits of using high-level language like C/C++. As of the ALGLIB version 4.00+, Commercial Edition provides a better set of SIMD kernels than the Free one.
The Commercial Edition also includes so-called Performance Backends - optional precompiled shared libraries that include vendor-optimized implementations of linear algebra and other functions, e.g. Intel MKL backend. These are different from SIMD kernels - the latter were developed by us and are deeply integrated into ALGLIB, while the former are optional external third-party components. ALGLIB can be compiled without a Performance Backend linked, but it can not be compiled without SIMD kernel units (you can compile them in the generic C mode, though).
Presently ALGLIB supports only x86/x64 SIMD, including SSE2, AVX2 and FMA instruction sets.
This support can be activated by compiling ALGLIB with AE_CPU=AE_INTEL macro symbol being #defined at the global level.
Sections below discuss how to compile ALGLIB in order to get the fastest executable possible or, alternatively, to get the most portable one.
Obviously, the fastest executable can be obtained by compiling entire ALGLIB (both low level kernels and the code relying on these kernels) using the best SIMD instruction set available, e.g. FMA. In this case compiler may use SIMD to accelerate both SIMD-capable kernels and generic C code, e.g. use SIMD registers to pass parameters to functions, perform quick memcpy() and so on.
In order to do so, two steps are necessary:
AE_CPU=AE_INTEL preprocessor symbol at the global levelThe former tells ALGLIB that it may use C/C++ SIMD intrinsics to accelerate computations. Depending on the compiler being used, the latter step can be done as follows:
/arch:AVX2 compiler switch (which activates both AVX2 and FMA)-mavx2 -mfma pair of options
The downside of this approach is that your entire application becomes less portable.
Of course, ALGLIB includes a CPU dispatcher which checks at runtime which SIMD instruction sets are available at your CPU.
If your CPU lacks FMA, ALGLIB won't call functions from kernels_fma.cpp.
Similarly, if you don't have AVX2, kernels_avx2.cpp will be ignored.
The problem is that because entire ALGLIB was compiled with SIMD support,
a compiler may insert SIMD instructions on its own to accelerate even generic C parts.
The point above applies in some degree to all modern compilers, although the behavior may change from version to version and may depend on the optimization settings.
In some cases (usually with optimization turned off) compilers generate completely portable code even in the presence of SIMD support.
As a counterexample, some MSVC versions are known to replace generic C code like a+b*c
by the fused multiply-adds when the code is compiled with /arch:AVX2
- which, by the way, violates the language specification.
If one needs a SIMD-capable application with portability guarantees, one has to:
AE_CPU=AE_INTEL preprocessor symbol at the global levelkernels_fma.cpp with SSE2/AVX2/FMA support enabled at the compiler levelkernels_avx2.cpp with SSE2/AVX2 support enabledkernels_sse2.cpp with SSE2 support enabled
ALGLIB guarantees that it won't call functions from kernels_fma.cpp without checking for FMA support first,
won't access kernels_avx2.cpp without checking for AVX2 and so on.
Thus, when the library is compiled this way, it will have guaranteed portability across x86/x64 systems.
By default, ALGLIB includes SIMD kernels for all x64 SIMD instruction sets present: SSE2, AVX2 and FMA. Of course, it has a CPU dispatcher which detects CPU support for SIMD and will choose proper SIMD kernel or generic C fallback. However, in some cases SIMD instruction sets should be deactivated at compile time. Most often it happens when one has to compile ALGLIB using some really outdated compiler which does not support post-SSE SIMD intrinsics.
It is possible to selectively disable a SIMD instruction set of your choice by combining AE_CPU=AE_INTEL #definition with one of the following #defines:
AE_NO_FMA to skip compilation of the FMA-capable kernelsAE_NO_AVX2 to skip compilation of the AVX2/FMA-capable kernelsAE_NO_SSE2 to skip compilation of all SSE2/AVX2/FMA SIMD kernels
If you want to use multithreaded capabilities of the Commercial Edition,
you should compile it in the OS-specific mode by #defining either AE_OS=AE_WINDOWS,
AE_OS=AE_POSIX or AE_OS=AE_LINUX (POSIX with Linux-specific extensions) at the compile time,
depending on the OS being used.
The former corresponds to any modern OS from the Windows family (the oldest OS we support is 32/64-bit Windows XP),
while the latter means almost any POSIX-compatible OS (or any OS from the Linux family).
ALGLIB will utilize OS capabilities for thread management: pthreads under POSIX systems, threading subset of WinAPI under Windows.
The paragraph above applies only to the Commercial Edition. The open source version is always OS-agnostic (does not use functions beyond C/C++ standard library) even in the presence of OS-specific definitions.
In this section we'll consider different compilation scenarios for free and commercial versions of ALGLIB - from simple platform-agnostic compilation to compiling/linking with MKL extensions.
We assume that you unpacked ALGLIB distribution in the current directory and saved here demo.cpp file,
whose code is given below. Thus, in the current directory you should have exactly one file (demo.cpp) and
exactly one subdirectory (alglib-cpp folder with ALGLIB distribution).
File listing below contains the very basic program which uses ALGLIB to perform matrix-matrix multiplication. After that program evaluates performance of GEMM (function being called) and prints result to console. We'll show how performance of this program continually increases as we add more and more sophisticated compiler options.
demo.cpp (WINDOWS EXAMPLE)
#include <stdio.h>
#include <windows.h>
#include "LinAlg.h"
double counter()
{
return 0.001*GetTickCount();
}
int main()
{
alglib::real_2d_array a, b, c;
int n = 2000;
int i, j;
double timeneeded, flops;
// Initialize arrays
a.setlength(n, n);
b.setlength(n, n);
c.setlength(n, n);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
a[i][j] = alglib::randomreal()-0.5;
b[i][j] = alglib::randomreal()-0.5;
c[i][j] = 0.0;
}
// Set global threading settings (applied to all ALGLIB functions);
// default is to perform serial computations, unless parallel execution
// is activated. Parallel execution tries to utilize all cores; this
// behavior can be changed with alglib::setnworkers() call.
alglib::setglobalthreading(alglib::parallel);
// Perform matrix-matrix product.
flops = 2*pow((double)n, (double)3);
timeneeded = counter();
alglib::rmatrixgemm(
n, n, n,
1.0,
a, 0, 0, 0,
b, 0, 0, 1,
0.0,
c, 0, 0);
timeneeded = counter()-timeneeded;
// Evaluate performance
printf("Performance is %.1f GFLOPS\n", (double)(1.0E-9*flops/timeneeded));
return 0;
}
Examples below cover Windows compilation from command line with MSVC.
It is very straightforward to adapt them to compilation from MSVC IDE - or to another compilers.
We assume that you already called %VCINSTALLDIR%\bin\amd64\vcvars64.bat batch file
which loads 64-bit build environment (or its 32-bit counterpart).
We also assume that current directory is clean before example is executed
(i.e. it has ONLY demo.cpp file and alglib-cpp folder).
We used 3.2 GHz 4-core CPU for this test.
First example covers platform-agnostic compilation without optimization settings - the most simple way to compile ALGLIB. This step is same in both open source and commercial editions. However, in platform-agnostic mode ALGLIB is unable to use all performance related features present in commercial edition.
We starts from copying all cpp and h files to current directory,
then we will compile them along with demo.cpp.
In this and following examples we will omit compiler output for the sake of simplicity.
OS-agnostic mode, no compiler optimizations
> copy alglib-cpp\src\*.* . > cl /I. /EHsc /Fedemo.exe *.cpp > demo.exe Performance is 0.7 GFLOPS
Well, 0.7 GFLOPS is not very impressing for a 3.2GHz CPU... Let's add /Ox to compiler parameters.
OS-agnostic mode, /Ox optimization
> cl /I. /EHsc /Fedemo.exe /Ox *.cpp
> demo.exe
Performance is 0.9 GFLOPS
Still not impressed. Let's turn on optimizations for x86 architecture: define AE_CPU=AE_INTEL, add /arch:AVX2.
This option provides some speed-up in both free and commercial editions of ALGLIB.
OS-agnostic mode, ALGLIB knows it is x86/x64
> cl /I. /EHsc /Fedemo.exe /Ox /DAE_CPU=AE_INTEL /arch:AVX2 *.cpp
> demo.exe
Performance is 4.5 GFLOPS
It is good, but we have 4 cores - and only one of them was used.
Defining AE_OS=AE_WINDOWS allows ALGLIB to use Windows threads to parallelize execution of some functions.
Starting from this moment, our example applies only to Commercial Edition.
ALGLIB knows it is Windows on x86/x64 CPU (COMMERCIAL EDITION)
> cl /I. /EHsc /Fedemo.exe /Ox /DAE_CPU=AE_INTEL /arch:AVX2 /DAE_OS=AE_WINDOWS *.cpp
> demo.exe
Performance is 16.0 GFLOPS
Not bad. And now we are ready to the final test - linking with MKL extensions.
Linking with MKL extensions differs a bit from standard way of linking with ALGLIB.
ALGLIB itself is compiled with one more preprocessor definition: we define AE_MKL symbol.
We also link ALGLIB with appropriate (32-bit or 64-bit) alglib???_??mkl.lib static library,
which is an import library for special lightweight MKL distribution, shipped with ALGLIB.
We also should copy to current directory appropriate alglib???_??mkl.dll binary file which contains Intel MKL.
Linking with MKL extensions (COMMERCIAL EDITION)
> copy alglib-cpp\addons-mkl\alglib*64mkl.lib . > copy alglib-cpp\addons-mkl\alglib*64mkl.dll . > cl /I. /EHsc /Fedemo.exe /Ox /DAE_CPU=AE_INTEL /DAE_OS=AE_WINDOWS /DAE_MKL *.cpp alglib*64mkl.lib > demo.exe Performance is 33.1 GFLOPS
From 0.7 GFLOPS to 33.1 GFLOPS - you may see that commercial version of ALGLIB is really worth it!
File listing below contains the very basic program which uses ALGLIB to perform matrix-matrix multiplication. After that program evaluates performance of GEMM (function being called) and prints result to console. We'll show how performance of this program continually increases as we add more and more sophisticated compiler options.
demo.cpp (LINUX EXAMPLE)
#include <stdio.h>
#include <sys/time.h>
#include "LinAlg.h"
double counter()
{
struct timeval now;
alglib_impl::ae_int64_t r, v;
gettimeofday(&now, NULL);
v = now.tv_sec;
r = v*1000;
v = now.tv_usec/1000;
r = r+v;
return 0.001*r;
}
int main()
{
alglib::real_2d_array a, b, c;
int n = 2000;
int i, j;
double timeneeded, flops;
// Initialize arrays
a.setlength(n, n);
b.setlength(n, n);
c.setlength(n, n);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
a[i][j] = alglib::randomreal()-0.5;
b[i][j] = alglib::randomreal()-0.5;
c[i][j] = 0.0;
}
// Set global threading settings (applied to all ALGLIB functions);
// default is to perform serial computations, unless parallel execution
// is activated. Parallel execution tries to utilize all cores; this
// behavior can be changed with alglib::setnworkers() call.
alglib::setglobalthreading(alglib::parallel);
// Perform matrix-matrix product.
flops = 2*pow((double)n, (double)3);
timeneeded = counter();
alglib::rmatrixgemm(
n, n, n,
1.0,
a, 0, 0, 0,
b, 0, 0, 1,
0.0,
c, 0, 0);
timeneeded = counter()-timeneeded;
// Evaluate performance
printf("Performance is %.1f GFLOPS\n", (double)(1.0E-9*flops/timeneeded));
return 0;
}
Examples below cover x64 Linux compilation from command line with GCC.
We assume that current directory is clean before example is executed
(i.e. it has ONLY demo.cpp file and alglib-cpp folder).
We used 2.3 GHz 2-core Skylake CPU with 2x Hyperthreading enabled for this test.
First example covers platform-agnostic compilation without optimization settings - the most simple way to compile ALGLIB. This step is same in both open source and commercial editions. However, in platform-agnostic mode ALGLIB is unable to use all performance related features present in commercial edition.
We starts from copying all cpp and h files to current directory,
then we will compile them along with demo.cpp.
In this and following examples we will omit compiler output for the sake of simplicity.
OS-agnostic mode, no compiler optimizations
> cp alglib-cpp/src/* . > g++ -I. -o demo.out *.cpp > ./demo.out Performance is 0.9 GFLOPS
Let's add -O3 to compiler parameters.
OS-agnostic mode, -O3 optimization
> g++ -I. -o demo.out -O3 *.cpp
> ./demo.out
Performance is 2.8 GFLOPS
Better, but not impressed. Let's turn on optimizations for x86 architecture: define AE_CPU=AE_INTEL, add -mavx2 -mfma.
This option provides some speed-up in both free and commercial editions of ALGLIB.
OS-agnostic mode, ALGLIB knows it is x86/x64
> g++ -I. -o demo.out -O3 -DAE_CPU=AE_INTEL -mavx2 -mfma *.cpp
> ./demo.out
Performance is 5.0 GFLOPS
It is good, but we have 4 cores (in fact, 2 cores - it is 2-way hyperthreaded system) and only one of them was used.
Defining AE_OS=AE_POSIX allows ALGLIB to use POSIX threads to parallelize execution of some functions.
You should also specify -pthread flag to link with pthreads standard library.
Starting from this moment, our example applies only to Commercial Edition.
ALGLIB knows it is POSIX OS on x86/x64 CPU (COMMERCIAL EDITION)
> g++ -I. -o demo.out -O3 -DAE_CPU=AE_INTEL -mavx2 -mfma -DAE_OS=AE_POSIX -pthread *.cpp
> ./demo.out
Performance is 9.0 GFLOPS
Not bad. You may notice that performance growth was ~2x, not 4x. The reason is that we tested ALGLIB on hyperthreaded system: although we have 4 logical cores, they share computational resources of just 2 physical cores. And now we are ready to the final test - linking with MKL extensions.
Linking with MKL extensions differs a bit from standard way of linking with ALGLIB.
ALGLIB itself is compiled with one more preprocessor definition: we define AE_MKL symbol.
We also link ALGLIB with appropriate alglib???_??mkl.so shared library,
which contains special lightweight MKL distribution shipped with ALGLIB.
We should note that on typical Linux system shared libraries are not loaded from current directory by default. Either you install them into one of the system directories, or use some way to tell linker/loader that you want to load shared library from some specific directory. For our example we choose to update LD_LIBRARY_PATH environment variable.
Linking with MKL extensions (COMMERCIAL EDITION, relevant for ALGLIB 3.13)
> cp alglib-cpp/addons-mkl/libalglib*64mkl.so . > ls *.so libalglib313_64mkl.so > g++ -I. -o demo.out -O3 -DAE_CPU=AE_INTEL -DAE_OS=AE_POSIX -pthread -DAE_MKL -L. *.cpp -lalglib313_64mkl > LD_LIBRARY_PATH=. > export LD_LIBRARY_PATH > ./demo.out Performance is 33.8 GFLOPS
Final result: from 0.9 GFLOPS to 33.8 GFLOPS!
Both open source and commercial versions of ALGLIB are 100% thread-safe as long as different user threads work with different instances of objects/arrays. Thread-safety is guaranteed by having no global shared variables.
However, any kind of sharing ALGLIB objects/arrays between different threads is potentially hazardous. Even when this object is seemingly used in the read-only mode!
Say, you use ALGLIB neural network NET to process two input vectors X0 and X1,
and get two output vectors Y0 and Y1.
You may decide that neural network is used in read-only mode which does not change state of NET,
because output is written to distinct arrays Y.
Thus, you may want to process these vectors from parallel threads.
But it is not read-only operation, even if it looks like that!
Neural network object NET allocates internal temporary buffers, which are modified by neural processing functions.
Thus, sharing one instance of neural network between two threads is thread-unsafe!
ALGLIB defines several conditional symbols (all start with "AE_" which means "ALGLIB environment") and two namespaces:
alglib_impl (contains computational core) and alglib (contains C++ interface).
Although this manual mentions both alglib_impl and alglib namespaces,
only alglib namespace should be used by you.
It contains user-friendly C++ interface with automatic memory management, exception handling and all other nice features.
alglib_impl is less user-friendly, is less documented,
and it is too easy to crash your system or cause a memory leak if you use it directly.
ALGLIB (ap.h header) defines several "basic" datatypes (types which are used by all packages) and many package-specific datatypes. "Basic" datatypes are:
alglib::ae_int_t - signed integer type used by libraryalglib::complex - double precision complex datatype, safer replacement for std::complexalglib::ap_error - exception which is thrown by libraryboolean_1d_array - 1-dimensional boolean arrayinteger_1d_array - 1-dimensional integer arrayreal_1d_array - 1-dimensional real (double precision) arraycomplex_1d_array - 1-dimensional complex arrayboolean_2d_array - 2-dimensional boolean arrayinteger_2d_array - 2-dimensional integer arrayreal_2d_array - 2-dimensional real (double precision) arraycomplex_2d_array - 2-dimensional complex arrayPackage-specific datatypes are classes which can be divided into two distinct groups:
The most important constants (defined in the ap.h header) from ALGLIB namespace are:
alglib::machineepsilon - small number which is close to the double precision &eps;, but is slightly largeralglib::maxrealnumber - very large number which is close to the maximum real number, but is slightly smaller alglib::minrealnumber - very small number which is close to the minimum nonzero real number, but is slightly largeralglib::fp_nan - NAN (non-signalling under most platforms except for PA-RISC, where it is signalling;
but when PA-RISC CPU is in its default state, it is silently converted to the quiet NAN)alglib::fp_posinf - positive infinityalglib::fp_neginf - negative infinity
The most important "basic" functions from ALGLIB namespace (ap.h header) are:
alglib::randomreal() - returns random real number from [0,1)alglib::randominteger(mx) - returns random integer number from [0,nx); mx must be less than RAND_MAXalglib::fp_eq(v1,v2) - makes IEEE-compliant comparison of two double precision numbers.
If numbers are represented with greater precision than specified by IEEE 754 (as with Intel 80-bit FPU), this functions converts them to 64 bits before comparing.alglib::fp_neq(v1,v2) - makes IEEE-compliant comparison of two double precision numbers.alglib::fp_less(v1,v2) - makes IEEE-compliant comparison of two double precision numbers.alglib::fp_less_eq(v1,v2) - makes IEEE-compliant comparison of two double precision numbers.alglib::fp_greater(v1,v2) - makes IEEE-compliant comparison of two double precision numbers.alglib::fp_greater_eq(v1,v2) - makes IEEE-compliant comparison of two double precision numbers.alglib::fp_isnan - checks whether number is NANalglib::fp_isposinf - checks whether number is +INFalglib::fp_isneginf - checks whether number is -INFalglib::fp_isinf - checks whether number is +INF or -INFalglib::fp_isfinite - checks whether number is finite value (possibly subnormalized)
ALGLIB (ap.h header) supports matrixes and vectors (one-dimensional and two-dimensional arrays) of variable size, with numeration starting from zero.
Everything starts from array creation. You should distinguish the creation of array class instance and the memory allocation for the array. When creating the class instance, you can use constructor without any parameters, that creates an empty array without any elements. An attempt to address them may cause the program failure.
You can use copy and assignment constructors that copy one array into another. If, during the copy operation, the source array has no memory allocated for the array elements, destination array will contain no elements either. If the source array has memory allocated for its elements, destination array will allocate the same amount of memory and copy the elements there. That is, the copy operation yields into two independent arrays with indentical contents.
You can also create array from formatted string like "[]", "[true,FALSE,tRUe]", "[[]]]" or "[[1,2],[3.2,4],[5.2]]" (note: '.' is used as decimal point independently from locale settings).
alglib::boolean_1d_array b1; b1 = "[true]"; alglib::real_2d_array r2("[[2,3],[3,4]]"); alglib::real_2d_array r2_1("[[]]"); alglib::real_2d_array r2_2(r2); r2_1 = r2; alglib::complex_1d_array c2; c2 = "[]"; c2 = "[0]"; c2 = "[1,2i]"; c2 = "[+1-2i,-1+5i]"; c2 = "[ 4i-2, 8i+2]"; c2 = "[+4i-2, +8i+2]"; c2 = "[-4i-2, -8i+2]";
After an empty array has been created, you can allocate memory for its elements, using the setlength() method.
The content of the created array elements is not defined.
If the setlength method is called for the array with already allocated memory, then, after changing its parameters,
the newly allocated elements also become undefined and the old content is destroyed.
alglib::boolean_1d_array b1; b1.setlength(2); alglib::integer_2d_array r2; r2.setlength(4,3);
Another way to initialize array is to call setcontent() method.
This method accepts pointer to data which are copied into newly allocated array.
Vectors are stored in contiguous order, matrices are stored row by row.
alglib::real_1d_array r1;
double _r1[] = {2, 3};
r1.setcontent(2,_r1);
alglib::real_2d_array r2;
double _r2[] = {11, 12, 13, 21, 22, 23};
r2.setcontent(2,3,_r2);
You can also attach real vector/matrix object to already allocated double precision array (attaching to boolean/integer/complex arrays is not supported). In this case, no actual data is copied, and attached vector/matrix object becomes a read/write proxy for external array.
alglib::real_1d_array r1;
double a1[] = {2, 3};
r1.attach_to_ptr(2,a1);
alglib::real_2d_array r2;
double a2[] = {11, 12, 13, 21, 22, 23};
r2.attach_to_ptr(2,3,_r2);
To access the array elements, an overloaded operator() or operator[] can used.
That is, the code addressing the element of array a with indexes [i,j] can look like
a(i,j) or a[i][j].
alglib::integer_1d_array a("[1,2,3]"); alglib::integer_1d_array b("[3,9,27]"); a[0] = b(0); alglib::integer_2d_array c("[[1,2,3],[9,9,9]]"); alglib::integer_2d_array d("[[3,9,27],[8,8,8]]"); d[1][1] = c(0,0);
You can access contents of 1-dimensional array by calling getcontent() method which returns pointer to the array memory.
For historical reasons 2-dimensional arrays do not provide getcontent() method, but you can use create reference to any element of array.
2-dimensional arrays store data in row-major order with aligned rows (i.e. generally distance between rows is not equal to number of columns).
You can get stride (distance between consequtive elements in different rows) with getstride() call.
alglib::integer_1d_array a("[1,2]"); alglib::real_2d_array b("[[0,1],[10,11]]"); alglib::ae_int_t *a_row = a.getcontent(); // all three pointers point to the same location double *b_row0 = &b[0][0]; double *b_row0_2 = &b(0,0); double *b_row0_3 = b[0]; // advancing to the next row of 2-dimensional array double *b_row1 = b_row0 + b.getstride();
Finally, you can get array size with length(), rows() or cols() methods:
alglib::integer_1d_array a("[1,2]"); alglib::real_2d_array b("[[0,1],[10,11]]"); printf("%ld\n", (long)a.length()); printf("%ld\n", (long)b.rows()); printf("%ld\n", (long)b.cols());
Most ALGLIB functions provide two interfaces: 'expert' and 'friendly'. What is the difference between two? When you use 'friendly' interface, ALGLIB:
When you use 'expert' interface, ALGLIB requires caller to explicitly specify size of input arguments. If vector/matrix is larger than size being specified (say, N), only N leading elements are used.
Here are several examples of 'friendly' and 'expert' interfaces:
#include "interpolation.h" ... alglib::real_1d_array x("[0,1,2,3]"); alglib::real_1d_array y("[1,5,3,9]"); alglib::real_1d_array y2("[1,5,3,9,0]"); alglib::spline1dinterpolant s; alglib::spline1dbuildlinear(x, y, 4, s); // 'expert' interface is used alglib::spline1dbuildlinear(x, y, s); // 'friendly' interface - input size is // automatically determined alglib::spline1dbuildlinear(x, y2, 4, s); // y2.length() is 5, but it will work alglib::spline1dbuildlinear(x, y2, s); // it won't work because sizes of x and y2 // are inconsistent
ALGLIB uses two error handling strategies:
What is actually done depends on function being used and error being reported:
alglib::ap_error exception.
Exception object has msg parameter which contains short description of error.To make things clear we consider several examples of error handling.
Example 1. mincgreate function creates nonlinear CG optimizer. It accepts problem size N and initial point X.
Several things can go wrong - you may pass array which is too short, filled by NAN's, or otherwise pass incorrect data.
However, this function returns no error code - so it throws an exception in case something goes wrong.
There is no other way to tell caller that something went wrong.
Example 2. rmatrixinverse function calculates inverse matrix.
It returns error code, which is set to +1 when problem is solved and is set to -3 if singular matrix was passed to the function.
However, there is no error code for matrix which is non-square or contains infinities.
Well, we could have created corresponding error codes - but we didn't.
So if you pass singular matrix to rmatrixinverse, you will get completion code -3.
But if you pass matrix which contains INF in one of its elements, alglib::ap_error will be thrown.
First error handling strategy (error codes) is used to report "frequent" errors which can occur during normal execution of user program. Second error handling strategy (exceptions) is used to report "rare" errors which are result of serious flaws in your program (or ALGLIB) - infinities/NAN's in the inputs, inconsistent inputs, etc.
ALGLIB (ap.h header) includes following Level 1 BLAS functions:
alglib::vdotproduct() family, which allows to calculate dot product of two real or complex vectorsalglib::vmove() family, which allows to copy real/complex vector to another location with optimal multiplication by real/complex valuealglib::vmoveneg() family, which allows to copy real/complex vector to another location with multiplication by -1alglib::vadd() and alglib::vsub() families, which allows to add or subtract two real/complex vectors with optimal multiplication by real/complex valuealglib::vmul() family, which implements in-place multiplication of real/complex vector by real/complex value
Each Level 1 BLAS function accepts input stride and output stride, which are expected to be positive.
Input and output vectors should not overlap.
Functions operating with complex vectors accept additional parameter conj_src, which specifies whether input vector is conjugated or not.
For each real/complex function there exists "simple" companion which accepts no stride or conjugation modifier. "Simple" function assumes that input/output stride is +1, and no input conjugation is required.
alglib::real_1d_array rvec("[0,1,2,3]"); alglib::real_2d_array rmat("[[1,2],[3,4]]"); alglib::complex_1d_array cvec("[0+1i,1+2i,2-1i,3-2i]"); alglib::complex_2d_array cmat("[[3i,1],[9,2i]]"); alglib::vmove(&rvec[0], 1, &rmat[0][0], rmat.getstride(), 2); // now rvec is [1,3,2,3] alglib::vmove(&cvec[0], 1, &cmat[0][0], rmat.getstride(), "No conj", 2); // now cvec is [3i, 9, 2-1i, 3-2i] alglib::vmove(&cvec[2], 1, &cmat[0][0], 1, "Conj", 2); // now cvec is [3i, 9, -3i, 1]
Here is full list of Level 1 BLAS functions implemented in ALGLIB:
double vdotproduct(
const double *v0,
ae_int_t stride0,
const double *v1,
ae_int_t stride1,
ae_int_t n);
double vdotproduct(
const double *v1,
const double *v2,
ae_int_t N);
alglib::complex vdotproduct(
const alglib::complex *v0,
ae_int_t stride0,
const char *conj0,
const alglib::complex *v1,
ae_int_t stride1,
const char *conj1,
ae_int_t n);
alglib::complex vdotproduct(
const alglib::complex *v1,
const alglib::complex *v2,
ae_int_t N);
void vmove(
double *vdst,
ae_int_t stride_dst,
const double* vsrc,
ae_int_t stride_src,
ae_int_t n);
void vmove(
double *vdst,
const double* vsrc,
ae_int_t N);
void vmove(
alglib::complex *vdst,
ae_int_t stride_dst,
const alglib::complex* vsrc,
ae_int_t stride_src,
const char *conj_src,
ae_int_t n);
void vmove(
alglib::complex *vdst,
const alglib::complex* vsrc,
ae_int_t N);
void vmoveneg(
double *vdst,
ae_int_t stride_dst,
const double* vsrc,
ae_int_t stride_src,
ae_int_t n);
void vmoveneg(
double *vdst,
const double *vsrc,
ae_int_t N);
void vmoveneg(
alglib::complex *vdst,
ae_int_t stride_dst,
const alglib::complex* vsrc,
ae_int_t stride_src,
const char *conj_src,
ae_int_t n);
void vmoveneg(
alglib::complex *vdst,
const alglib::complex *vsrc,
ae_int_t N);
void vmove(
double *vdst,
ae_int_t stride_dst,
const double* vsrc,
ae_int_t stride_src,
ae_int_t n,
double alpha);
void vmove(
double *vdst,
const double *vsrc,
ae_int_t N,
double alpha);
void vmove(
alglib::complex *vdst,
ae_int_t stride_dst,
const alglib::complex* vsrc,
ae_int_t stride_src,
const char *conj_src,
ae_int_t n,
double alpha);
void vmove(
alglib::complex *vdst,
const alglib::complex *vsrc,
ae_int_t N,
double alpha);
void vmove(
alglib::complex *vdst,
ae_int_t stride_dst,
const alglib::complex* vsrc,
ae_int_t stride_src,
const char *conj_src,
ae_int_t n,
alglib::complex alpha);
void vmove(
alglib::complex *vdst,
const alglib::complex *vsrc,
ae_int_t N,
alglib::complex alpha);
void vadd(
double *vdst,
ae_int_t stride_dst,
const double *vsrc,
ae_int_t stride_src,
ae_int_t n);
void vadd(
double *vdst,
const double *vsrc,
ae_int_t N);
void vadd(
alglib::complex *vdst,
ae_int_t stride_dst,
const alglib::complex *vsrc,
ae_int_t stride_src,
const char *conj_src,
ae_int_t n);
void vadd(
alglib::complex *vdst,
const alglib::complex *vsrc,
ae_int_t N);
void vadd(
double *vdst,
ae_int_t stride_dst,
const double *vsrc,
ae_int_t stride_src,
ae_int_t n,
double alpha);
void vadd(
double *vdst,
const double *vsrc,
ae_int_t N,
double alpha);
void vadd(
alglib::complex *vdst,
ae_int_t stride_dst,
const alglib::complex *vsrc,
ae_int_t stride_src,
const char *conj_src,
ae_int_t n,
double alpha);
void vadd(
alglib::complex *vdst,
const alglib::complex *vsrc,
ae_int_t N,
double alpha);
void vadd(
alglib::complex *vdst,
ae_int_t stride_dst,
const alglib::complex *vsrc,
ae_int_t stride_src,
const char *conj_src,
ae_int_t n,
alglib::complex alpha);
void vadd(
alglib::complex *vdst,
const alglib::complex *vsrc,
ae_int_t N,
alglib::complex alpha);
void vsub(
double *vdst,
ae_int_t stride_dst,
const double *vsrc,
ae_int_t stride_src,
ae_int_t n);
void vsub(
double *vdst,
const double *vsrc,
ae_int_t N);
void vsub(
alglib::complex *vdst,
ae_int_t stride_dst,
const alglib::complex *vsrc,
ae_int_t stride_src,
const char *conj_src,
ae_int_t n);
void vsub(
alglib::complex *vdst,
const alglib::complex *vsrc,
ae_int_t N);
void vsub(
double *vdst,
ae_int_t stride_dst,
const double *vsrc,
ae_int_t stride_src,
ae_int_t n,
double alpha);
void vsub(
double *vdst,
const double *vsrc,
ae_int_t N,
double alpha);
void vsub(
alglib::complex *vdst,
ae_int_t stride_dst,
const alglib::complex *vsrc,
ae_int_t stride_src,
const char *conj_src,
ae_int_t n,
double alpha);
void vsub(
alglib::complex *vdst,
const alglib::complex *vsrc,
ae_int_t N,
double alpha);
void vsub(
alglib::complex *vdst,
ae_int_t stride_dst,
const alglib::complex *vsrc,
ae_int_t stride_src,
const char *conj_src,
ae_int_t n,
alglib::complex alpha);
void vsub(
alglib::complex *vdst,
const alglib::complex *vsrc,
ae_int_t N,
alglib::complex alpha);
void vmul(
double *vdst,
ae_int_t stride_dst,
ae_int_t n,
double alpha);
void vmul(
double *vdst,
ae_int_t N,
double alpha);
void vmul(
alglib::complex *vdst,
ae_int_t stride_dst,
ae_int_t n,
double alpha);
void vmul(
alglib::complex *vdst,
ae_int_t N,
double alpha);
void vmul(
alglib::complex *vdst,
ae_int_t stride_dst,
ae_int_t n,
alglib::complex alpha);
void vmul(
alglib::complex *vdst,
ae_int_t N,
alglib::complex alpha);
ALGLIB (ap.h header) has alglib::read_csv() function
which allows to read data from CSV file.
Entire file is loaded into memory as double precision 2D array (alglib::real_2d_array object).
This function provides following features:
See comments on alglib::read_csv() function for more information about its functionality.
Commercial version of ALGLIB for C++ features four important improvements over open source one:
Commercial ALGLIB for C++ can utilize SIMD instructions supported by Intel and AMD processors more extensively than the Free Edition. This feature is optional and must be explicitly turned on during compile-time. If you do not activate it, ALGLIB will use generic C code, without any processor-specific assembly/intrinsics.
In order to turn on x64-specific optimizations,
you should define AE_CPU=AE_INTEL preprocessor definition at global level.
It will tell ALGLIB to use SIMD intrinsics supported by GCC, MSVC and Intel compilers.
Additionally you should tell compiler to generate SIMD-capable code.
Configuration of SIMD support is discussed in a more detailed manner in the separate section of the Reference Manual.
Commercial version of ALGLIB includes out-of-the-box support for multithreading. Many (not all) computationally intensive problems can be solved in multithreaded mode. You should read comments on specific ALGLIB functions to determine what can be multithreaded and what can not.
ALGLIB does not depend on vendor/compiler support for technologies like OpenMP/MPI/... Under Windows ALGLIB uses OS threads and its own synchronization framework. Under POSIX-compatible OS (Linux, FreeBSD, NetBSD, OpenBSD, ...) ALGLIB uses POSIX Threads (standard *nix library which is shipped with any POSIX system) with its threading and synchronization primitives. It gives ALGLIB unprecedented portability across operating systems and compilers. ALGLIB does not depend on presence of any custom multithreading library or compiler support for any multithreading technology.
You should compile ALGLIB in OS-specific mode by #defining either
AE_OS=AE_WINDOWS or AE_OS=AE_POSIX
(or AE_OS=AE_LINUX, which means "POSIX with Linux extensions") at the compile time,
depending on the OS being used.
The former corresponds to any OS modern from the Windows family (and down to an antique 32/64-bit Windows XP),
while the latter two mean almost any POSIX-compatible OS or any OS from the Linux family.
When compiling on POSIX/Linux, do not forget to link ALGLIB with libpthread library.
When compiled without OS-specific switches, ALGLIB runs in OS-agnostic mode and ignores all kinds of parallelism settings.
ALGLIB supports two types of parallelism:
Internal parallelism refers to ALGLIB's capability to speed up operations that are embedded within its own functions. When this feature is active, its presence is mostly noticeable through the reduced execution time of computation-heavy functions. To use internal parallelism, you only need to enable it in ALGLIB, without any modifications to your existing code. This parallelism is available in a range of ALGLIB functions, covering areas from linear algebra to data analysis.
Callback parallelism, on the other hand, allows certain ALGLIB optimizers to send multiple parallel requests to user-defined callbacks. For example, numerical differentiation is inherently parallel as each component of a gradient can be computed independently. Similarly, optimizers like differential evolution can issue several requests simultaneously, which can be processed in parallel.
While it is ALGLIB who manages the creation and termination of computing threads to parallelize these batch requests, callback parallelism still requires you to provide a thread-safe callback. This callback must be capable of handling multiple simultaneous calls from multiple threads. Unlike internal parallelism, callback parallelism is not automatically managed by ALGLIB; it requires active cooperation from your side to ensure that your code is re-entrant and thread-safe.
Both types of parallelism can be used in various combinations. You might choose to employ only internal parallelism, only callback parallelism, both, or neither.
ALGLIB provides the flexibility to define parallelism settings at both global and function-specific levels.
Global settings can be configured using the alglib::setglobalflags function.
For function-local settings, you specify them by passing an instance of the alglib::xparams type
to the particular computational function you are using.
It's important to note that these function-local settings are actually call-local.
This means that making simultaneous calls to the same function with different settings will result in the use of different parallelism types for each call.
Another important point is that function-local settings do not propagate to other (even connected) functions.
E.g., if you create an instance of MINNLC optimizer with minnlccreate and then start optimization with minnlcoptimize,
then it is the latter function which actually does the job.
Any parallelism-related settings should be passed directly to minnlcoptimize and not to minnlccreate,
because minnlccreate does nothing except for allocating data structures.
The alglib::xparams structure, which stores parallelism settings, can be set to the following values:
alglib::serial - indicates no internal parallelism.alglib::parallel - enables internal parallelism.alglib::serial_callbacks - disables callback parallelism.alglib::parallel_callbacks - enables parallel callbacks.There are also additional values that are used to control interaction with performance backends. These values are discussed in the corresponding manual section.
You can combine values pertaining to different types of parallelism (internal and callback) using the OR operator,
such as alglib::serial|alglib::parallel_callbacks.
However, attempting to combine conflicting values like alglib::parallel_callbacks|alglib::serial_callbacks will result in an invalid setting.
If a value for a specific type of parallelism is not provided at the function-local level
— such as alglib::serial, which defines settings for internal parallelism but omits callback parallelism —
then that specific setting defaults to the global settings as determined by alglib::setglobalthreading.
In cases where no global settings are specified for a particular parallelism type, serial execution is the default choice.
IMPORTANT: Activating internal parallelism in ALGLIB does not automatically mean that computations will be parallelized. ALGLIB assesses whether the problem at hand is sufficiently large to warrant efficient parallelization. This decision is made automatically by the library. In contrast, enabling callback parallelism always leads to ALGLIB creating worker threads for handling parallel requests.
This occurs even if the requests are too lightweight to benefit from multithreading. Be aware that this could potentially slow down your application due to the overhead of parallel synchronization, rather than speeding it up. The reason is that ALGLIB sees user-defined callbacks as black boxes. Therefore, when using callback parallelism, the decision on its effectiveness rests with you.
ALGLIB automatically determines number of cores on application startup.
On Windows it is done using GetSystemInfo() call.
On POSIX systems ALGLIB performs sysconf(_SC_NPROCESSORS_ONLN) system call.
This system call is supported by all modern POSIX-compatible systems.
By default, ALGLIB uses all available cores (when told to parallelize calculations).
Such behavior may be changed with setnworkers() call:
alglib::setnworkers(0) = use all coresalglib::setnworkers(-1) = leave one core unusedalglib::setnworkers(-2) = leave two cores unusedalglib::setnworkers(+2) = use 2 cores (even if you have more)
You may want to specify maximum number of worker threads during compile time
by means of preprocessor definition AE_NWORKERS=N.
You can add this definition to compiler command line or change corresponding project settings in your IDE.
Here N can be any positive number.
ALGLIB will use exactly N worker threads, unless being told to use less by setnworkers() call.
Some old POSIX-compatible operating systems do not support sysconf(_SC_NPROCESSORS_ONLN) system call
which is required in order to automatically determine number of active cores.
On these systems you should specify number of cores manually at compile time.
Without it ALGLIB will run in the single-threaded mode.
As mentioned earlier, callback parallelism is a powerful feature that enables faster numerical differentiation and faster highly parallel optimization methods like differential evolution. To effectively use callback parallelism, it is essential that:
Achieving the latter can be challenging if your callback uses temporary data structures (one instance per invocation). Generally, it is inefficient to allocate temporary arrays on heap every time the callback is invoked. Memory allocation and deallocation requires synchronization which hampers parallelism. The only exception is when evaluating your objective function is so costly that memory allocation becomes a negligible factor.
Similarly, storing preallocated temporaries in a lock-protected pool can also be inefficient. Lock-free data structures relying on interlocked operations offer a somewhat better option, but even lock-free code still involves some synchronization, which can become a bottleneck.
The ideal strategy is to design your callback code to avoid synchronization entirely.
This can be achieved by preallocating an array of alglib::getmaxnworkers() temporaries at the outset
and using alglib::getcallbackworkeridx() to identify the worker thread that invoked the callback.
This index allows retrieval of a temporary structure from the array.
Since different worker threads have distinct indexes, this approach achieves thread safety with no synchronization required.
This option needs C++11 or later because it relies on thread-local storage being properly supported by the language.
When compiled under earlier versions of the standard, alglib::getcallbackworkeridx() is not available.
Simultaneous multithreading (SMT), also known as Hyper-threading, is a CPU design where several (usually two) logical cores share resources of one physical core. Say, on a dual-core system with 2x HT scale factor you will see 4 logical cores. Each pair of these 4 cores, however, share same hardware resources. Thus, you may get only marginal speedup when running highly optimized software which fully utilizes CPU resources.
Say, if one thread occupies floating-point unit, another thread on the same physical core may work with integer numbers at the same time without any performance penalties. In this case you may get some speedup due to having additional cores. But if both threads keep FPU unit 100% busy, they won't get any multithreaded speedup.
So, if 2 math-intensive threads are dispatched by OS scheduler to different physical cores, you will get 2x speedup due to use of multithreading. But if these threads are dispatched to different logical cores - but same physical core - you won't get any speedup at all! One physical core will be 100% busy, and another one will be 100% idle. From the other side, if you start four threads instead of two, your system will be 100% utilized independently of thread scheduling details.
Let us stress it one more time - multithreading speedup on SMT systems is highly dependent on number of threads you are running and decisions made by OS scheduler. It is not 100% deterministic! With "true SMP" when you run 2 threads, you get 2x speedup (or 1.95, or 1.80 - it depends on algorithm, but this factor is always same). With SMT when you run 2 threads you may get your 2x speedup - or no speedup at all. Modern OS schedulers do a good job on single-socket hardware, but even in this "simple" case they give no guarantees of fair distribution of hardware resources. And things become a bit tricky when you work with multi-socket hardware. On SMT systems the only guaranteed way to 100% utilize your CPU is to create as many worker threads as there are logical cores. In this case OS scheduler has no chance to make its work in a wrong way.
ALGLIB is a self-contained numerical toolkit that comes with its own implementation of all of its functions. ALGLIB also has its own multithreading and SIMD kernels, so it provides a good performance without linking with any external library.
Nevertheless, it is possible to further accelerate ALGLIB by linking with optimized software libraries provided by hardware vendors. These libraries can be used to accelerate low-to-mid-level operations like BLAS or sparse direct solvers (depending on a specific backend chosen). The acceleration can be due to more efficient SIMD usage (most typically), or due to different algorithms used. ALGLIB can export accelerated functionality as its 'primary' function - e.g., a request to solve a linear system can be forwarded directly to a performance backend. It can also use backend to accelerate higher-level functions that depend on this functionality (e.g., SQP or interior point optimizers spend a lot of time doing basic linear algebra).
ALGLIB comes with several precompiled backends (shared libraries with standardized APIs) that can be linked without downloading entire SDK from a hardware vendor website. For exampe, in order to use Intel MKL you do not have to install entire oneAPI toolkit - using a single shared library included into commercial ALGLIB is enough. You can use backend libraries as a part of ALGLIB under a combination of ALGLIB License Agreement and corresponding license terms for the backend library (included into ALGLIB archive). Doing so is allowed by license agreements with corresponding vendors.
It is also possible to link ALGLIB with your own installation of a vendor's library. For example, it makes sense if you already use the same vendor library in your application. Below we will discuss both options.
A precompiled performance backend is a shared library (DLL and import LIB under Windows, SO under Linux/POSIX)
that sits in the performance-backends/backend-name directory of your commercial ALGLIB distribution.
You can treat it as a black box that provides accelerated functions.
All precompiled backends export their functions via single unified API used by ALGLIB. Thus, they can be linked interchangeably without making any changes to the way ALGLIB itself is compiled. If a function (e.g., direct sparse solver) is missing in this specific backend, it simply returns 'unsupported' and ALGLIB falls back to its own implementation. No matter which specific backend is linked, you can always use full set of ALGLIB functions.
The core dispatcher that handles requests for a potentially accelerated functionality is located in the ap.cpp file.
Depending on specific preprocessor symbols #defined during compilation and on problem sizes, it can forward a call to a generic C implementation,
to one of the SIMD-optimized versions located in kernels_avx2/fma/etc.cpp, or to a performance backend currently linked:
AE_CPU is #defined, a call can be forwarded to an ALGLIB own SIMD kernelALGLIB_LINK_PERFORMANCE_BACKEND (or one of backend-specific symbols) is #defined, a call can be forwarded to a backend
ALGLIB provides the flexibility to define performance backend settings at both global and function-specific levels.
Global settings can be configured using the alglib::setglobalflags function.
For function-local settings, you specify them by passing an instance of the alglib::xparams type
to the particular computational function you are using.
It's important to note that these function-local settings are actually call-local.
This means that making simultaneous calls to the same function with different settings will result in the use of different settings for each call.
Another important point is that function-local settings do not propagate to other (even connected) functions.
E.g., if you create an instance of MINNLC optimizer with minnlccreate and then start optimization with minnlcoptimize,
then it is the latter function which actually does the job.
Any backend-related settings should be passed directly to minnlcoptimize and not to minnlccreate,
because minnlccreate does nothing except for allocating data structures.
The alglib::xparams structure can have the following backend-related values:
alglib::backend_linalg and alglib::no_backend_linalg - BLAS/LAPACK usage.alglib::backend_dss and alglib::no_backend_dss - direct sparse solver usage.There are also additional values that are used to control parallelism. These values are discussed in the corresponding manual section.
You can combine values pertaining to different subsets of backend functionality (basic linear algebra, direct sparse solvers) using the OR operator,
such as alglib::backend_linalg|alglib::no_backend_dss.
However, attempting to combine conflicting values like alglib::backend_linalg|alglib::no_backend_linalg will result in an undefined behavior.
If a value for a specific type of backend functionality is not provided at the function-local level
(e.g., only alglib::backend_linalg is passed which defines settings for BLAS but omits DSS),
then this specific setting defaults to the global settings as determined by alglib::setglobalflags.
In cases where no global settings are specified, ALGLIB chooses a default option on its own.
IMPORTANT: Activating backend does not automatically mean that computations will always be passed to the backend. ALGLIB assesses whether the problem at hand is sufficiently large so that the additional overhead from calling backend is negligible.
This performance backend is a lightweight subset of Intel MKL that includes only BLAS and LAPACK kernels. The backend includes only single-threaded versions of BLAS/LAPACK, with parallelism done at ALGLIB level.
Compiling and linking with the backend. In order to activate ALGLIB-backend connection, ALGLIB itself must be compiled as follows:
ALGLIB_LINK_PERFORMANCE_BACKEND must be #defined at the project level in order to activate ALGLIB-backend connection.
AE_OS=AE_WINDOWS (AE_OS=AE_POSIX, AE_OS=AE_LINUX) must be #defined to activate multithreading capabilities
AE_CPU=AE_INTEL must be #defined to use SIMD instructions provided by x86/x64 CPU's for the rest of ALGLIB
After that, an appropriate shared library from performance-backends/mklmini has to be linked with your program and ALGLIB:
Each library in the performance-backends/mklmini directory is a highly portable standalone binary with no external dependencies, except for standard system libraries.
You do not have to install Intel MKL yourself in order to use this backend.
Compatibility. The backend is highly compatible with all user configurations: serial applications, parallel applications using OS threads, parallel applications using various OpenMP implementations.
Activating the backend.
BLAS/LAPACK kernels are active by default, unless explicitly turned off with the alglib::no_backend_linalg flag.
Performance. Linking with this backend results in the following performance-related changes:
This performance backend includes a larger subset of Intel MKL than mklmini: BLAS/LAPACK kernels plus PARDISO (a direct sparse solver by Intel) for x86/x64 architectures. This backend includes only single-threaded versions of BLAS/LAPACK kernels and PARDISO. PARDISO is always executed serially, BLAS/LAPACK are parallelized at ALGLIB level.
Compiling and linking with the backend. In order to activate ALGLIB-backend connection, ALGLIB itself must be compiled as follows:
ALGLIB_LINK_PERFORMANCE_BACKEND must be #defined at the project level in order to activate ALGLIB-backend connection.
AE_OS=AE_WINDOWS (AE_OS=AE_POSIX, AE_OS=AE_LINUX) must be #defined to activate multithreading capabilities
AE_CPU=AE_INTEL must be #defined to use SIMD instructions provided by x86/x64 CPU's for the rest of ALGLIB
After that, an appropriate shared library from performance-backends/mklfull has to be linked with your program and ALGLIB:
Each library in the performance-backends/mklfull directory is a highly portable standalone binary with no external dependencies, except for standard system libraries.
You do not have to install Intel MKL yourself in order to use this backend.
Compatibility. The backend is highly compatible with all user configurations: serial applications, parallel applications using OS threads, parallel applications using various OpenMP implementations.
Activating the backend.
The backend includes two functionally distinct parts: BLAS/LAPACK kernels and DSS (Direct Sparse Solver) functionality.
BLAS/LAPACK kernels are active by default, unless explicitly turned off with the alglib::no_backend_linalg flag.
DSS functionality is turned off by default (because PARDISO is not always superior to ALGLIB),
but can be activated by passing alglib::backend_dss flag to ALGLIB.
Performance. Linking with this backend results in the following performance-related changes:
alglib::backend_dss flag.
For large sparse matrices with big amounts of fill-in PARDISO often provides several-fold improvement over ALGLIB DSS.
However, for highly sparse problems ALGLIB DSS is typically much faster than PARDISO - from several times to an order of magnitude.
Performance changes are most noticeable for sparse direct solvers, continuous and mixed-integer optimizers.
The short summary is that ALGLIB DSS provides uniform performance for all problem classes,
while PARDISO shines only for some specific problem types.
If you want to use your own installation of MKL, then you should compile ALGLIB as follows:
1. Add to your project alglib2pbl.c file from the /performance-backends directory
and compile it (as C file) along with the rest of ALGLIB.
This C file implements interface between ALGLIB and performance backends.
Having this file in your project and defining appropriate preprocessor definition (see below) results in ALGLIB using MKL functions.
However, this C file is just interface!
It is your responsibility to make sure that C/C++ compiler can find MKL headers,
and appropriate MKL static/dynamic libraries are linked to your application.
2. ALGLIB and alglib2pbl.c should be compiled with all the necessary CPU and OS-specific preprocessor definitions
(AE_OS=AE_WINDOWS or AE_OS=AE_LINUX, and AE_CPU=AE_INTEL).
Additionally, you should #define AE_MKL at the global level.
This definition tells ALGLIB to use all functions of Intel MKL (BLAS, LAPACK, direct sparse solvers, etc).
Additionally, you can #define AE_LIGHTWEIGHT_PBL if you want ALGLIB to use only BLAS/LAPACK kernels.
Red Zone is a fixed size area added before and after each dynamically allocated block. Red Zone is filled by the special red zone control value during its allocation. When the dynamically allocated block is freed, its control value is checked. Any change means that someone (either ALGLIB or user code that works with ALGLIB-allocated arrays) performed an out-of-bounds write. Red Zones are essential for finding memory access errors that silently corrupt your data and/or crash your program.
ALGLIB for C++ comes with Red Zones support disabled by default.
It can be enabled by #defining ALGLIB_REDZONE=512 (or some other multiple of 64 bytes) at the global level.
Larger values mean that a larger buffer is added, and a better opportunity to detect large misses.
E.g., if your write is just 8 bytes away from the array, a 64-byte red zone is enough to detect it.
On the other hand, a 1024-byte miss needs a red zone at least that large.
ALGLIB checks the red zone of the dynamic array when it is deallocated by its destructor (or reallocated).
In case the red zone is damaged, ALGLIB prints a message to stderr and terminates the program.
Two kinds of errors are distinguished: writes past the end, and writes prior to the beginning.
You can find out the exact variable being damaged by looking to the trace stack.
It is one which is currently deallocated or reallocated.
Red zones add some memory overhead (insignificant for large arrays) and some modest performance overhead. Your program may become a few percent slower (in the very worst case - a few tens of percent).
ALGLIB uses and provides to its users its own random numbers generator. Whilst it is not cryptographically secure, it is good enough for scientific purposes. However, this generator has to be primed with an external entropy source - one which provides random or pseudorandom seeds.
In its default configuration ALGLIB obtains these seeds with stdlib rand(),
whish was chosen as the default entropy source for portability reasons.
In most cases it is acceptable - all we need is just two integers
which will be used to prime a high-quality generator implemented in ALGLIB.
However, some users may prefer to use other sources of entropy.
Entropy source used by ALGLIB can be configured by #defining ALGLIB_ENTROPY_SRC to be one of the following:
ALGLIB_ENTROPY_SRC_STDRAND to use the default source - rand() function provided by stdlib.hALGLIB_ENTROPY_SRC_OPENSSL to use OpenSSL facilities as the entropy source.
One has to have OpenSSL installed on its system to use this option.
ALGLIB for C++ can be compiled in exception-free mode, with exceptions
(throw/try/catch constructs) being disabled at compiler level.
Such feature is sometimes used by developers of embedded software.
ALGLIB uses two-level model of errors:
"expected" errors (like degeneracy of linear system or inconsistency of linear constraints)
are reported with dedicated completion codes,
and "critical" errors (like malloc failures, unexpected NANs/INFs in the input data and so on)
are reported with exceptions.
The idea is that it is hard to put (and handle) completion codes in every ALGLIB function,
so we use exceptions to signal errors which should never happen under normal circumstances.
Internally ALGLIB for C++ is implemented as C++ wrapper around computational core written in pure C.
Thus, internals of ALGLIB core use C-specific methods of error handling -
completion codes and setjmp/longjmp functions.
These error handling strategies are combined with sophisticated machinery of C memory management
which makes sure that not even a byte of dynamic memory is lost when we make longjmp to the error handler.
So, the only point where C++ exceptions are actually used is a boundary between C core and C++ interface.
If you choose to use exceptions (default mode), ALGLIB will throw an exception with short textual description of the situation. And if you choose to work without exceptions, ALGLIB will set global error flag and silently return from the current function/constructor/... instead of throwing an exception. Due to portability issues this error flag is made to be a non-TLS variable, i.e. it is shared between different threads. So, you can use exception-free error handling only in single-threaded programs - although multithreaded programs won't break, there is no way to determine which thread caused an "exception without exceptions".
Exception-free method of reporting critical errors can be activated by #defining two preprocessor symbols at global level:
AE_NO_EXCEPTIONS - to switch from exception-based to exception-free codeAE_THREADING=AE_SERIAL_UNSAFE - to confirm that you are aware of limitations associated
with exception-free mode (it does not support multithreading)
We must also note that exception-free mode is incompatible with OS-aware compiling:
you can not have AE_OS=??? defined together with AE_NO_EXCEPTIONS.
After you #define all the necessary preprocessor symbols, two functions will appear in alglib namespace:
bool alglib::get_error_flag(const char **p_msg = NULL),
which returns current error status (true is returned on error),
with optional char** parameter used to get human-readable error message.
void alglib::clear_error_flag(), which clears error flag
(ALGLIB functions set flag on failure, but do not clear it on successful calls)
You must check error flag after EVERY operation with ALGLIB objects and functions. In addition to calling computational ALGLIB functions, following kinds of operations may result in "exception":
malloc() call which may fail.
malloc)
setlength()/setcontents()
and attaching to external memory with attach_to_ptr()
Due to ALGLIB modular structure it is possible to selectively enable/disable some of its subpackages along with their dependencies. Deactivation of ALGLIB source code is performed at preprocessor level - compiler does not even see disabled code. Partial compilation can be used for two purposes:
You can activate partial compilation by #defining at global level following symbols:
AE_PARTIAL_BUILD - to disable everything not enabled by default
AE_COMPILE_SUBPACKAGE - to selectively enable subpackage SUBPACKAGE,
with its name given in upper case (case sensitive).
You may combine several definitions like this in order to enable several subpackages.
Subpackage names can be found in the list of ALGLIB packages and subpackages.
There are three test suites in ALGLIB: computational tests, interface tests, extended tests.
Computational tests are located in /tests/test_c.cpp.
They are focused on numerical properties of algorithms, stress testing and "deep" tests (large automatically generated problems).
They require significant amount of time to finish (tens of minutes).
Interface tests are located in /tests/test_i.cpp.
These tests are focused on ability to correctly pass data between computational core and caller, ability to detect simple problems in inputs,
and on ability to at least compile ALGLIB with your compiler.
They are very fast (about a minute to finish including compilation time).
Extended tests are located in /tests/test_x.cpp.
These tests are focused on testing some special properties
(say, testing that cloning object indeed results in 100% independent copy being created)
and performance of several chosen algorithms.
Running test suite is easy - just
test_c.cpp, test_i.cpp or test_x.cpp)
along with the rest of the library
If you want to be sure that ALGLIB will work with some sophisticated optimization settings, set corresponding flags during compile time.
If your compiler/system are not in the list of supported ones, we recommend you to run both test suites. But if you are running out of time, run at least test_i.cpp.
8.1
| ||
| hqrnd | High quality random numbers generator | |
| nearestneighbor | Nearest neighbor search: approximate and exact | |
| xdebug | Debug functions to test ALGLIB interface generator | |
8.2
| ||
| bdss | Basic dataset functions | |
| clustering | Clustering functions (hierarchical, k-means, k-means++) | |
| datacomp | Backward compatibility functions | |
| dforest | Decision forest classifier (regression model) | |
| filters | Different filters used in data analysis | |
| knn | K Nearest Neighbors classification/regression | |
| lda | Linear discriminant analysis | |
| linreg | Linear models | |
| logit | Logit models | |
| mcpd | Markov Chains for Population/proportional Data | |
| mlpbase | Basic functions for neural networks | |
| mlpe | Basic functions for neural ensemble models | |
| mlptrain | Neural network training | |
| pca | Principal component analysis | |
| ssa | Singular Spectrum Analysis | |
8.3
| ||
| odesolver | Ordinary differential equation solver | |
8.4
| ||
| conv | Fast real/complex convolution | |
| corr | Fast real/complex cross-correlation | |
| fft | Real/complex FFT | |
| fht | Real Fast Hartley Transform | |
8.5
| ||
| autogk | Adaptive 1-dimensional integration | |
| gkq | Gauss-Kronrod quadrature generator | |
| gq | Gaussian quadrature generator | |
8.6
| ||
| fitsphere | Fitting circle/sphere to data (least squares, minimum circumscribed, maximum inscribed, minimum zone) | |
| idw | Inverse distance weighting: interpolation/fitting with improved Shepard-like algorithm | |
| intcomp | Backward compatibility functions | |
| lsfit | Fitting with least squates target function (linear and nonlinear least-squares) | |
| parametric | Parametric curves | |
| polint | Polynomial interpolation/fitting | |
| ratint | Rational interpolation/fitting | |
| rbf | Scattered N-dimensional interpolation with RBF models | |
| spline1d | 1D spline interpolation/fitting | |
| spline2d | 2D spline interpolation and fitting | |
| spline3d | 3D spline interpolation | |
8.7
| ||
| ablas | Level 2 and Level 3 BLAS operations | |
| bdsvd | Bidiagonal SVD | |
| evd | Direct and iterative eigensolvers | |
| inverseupdate | Sherman-Morrison update of the inverse matrix | |
| matdet | Determinant calculation | |
| matgen | Random matrix generation | |
| matinv | Matrix inverse | |
| normestimator | Estimates norm of the sparse matrix (from below) | |
| ortfac | Real/complex QR/LQ, bi(tri)diagonal, Hessenberg decompositions | |
| rcond | Condition number estimates | |
| schur | Schur decomposition | |
| sparse | Sparse matrices | |
| spdgevd | Generalized symmetric eigensolver | |
| svd | Singular value decomposition | |
| trfac | LU and Cholesky decompositions (dense and sparse) | |
8.8
| ||
| minlpsolvers | Mixed-integer nonlinear programming solver (structured and black-box problems) | |
8.9
| ||
| lpsolvers | Linear programming suite | |
| minbc | Box constrained optimizer with fast activation of multiple constraints per step | |
| minbleic | Bound constrained optimizer with additional linear equality/inequality constraints | |
| mincg | Conjugate gradient optimizer | |
| mincomp | Backward compatibility functions | |
| mindf | Derivative-free and global optimization | |
| minlbfgs | Limited memory BFGS optimizer | |
| minlm | Improved Levenberg-Marquardt optimizer | |
| minmo | Multi-objective optimizer | |
| minnlc | Nonlinear programming solver (analytic gradient, numdiff, model-based DFO) | |
| minns | Nonsmooth constrained optimizer | |
| minqp | Quadratic optimization with linear, quadratic and conic constraints | |
| nls | Nonlinear least squares (derivative-free) | |
| optguardapi | OptGuard integrity checking for nonlinear models | |
| opts | Internal service functions (core types) | |
8.10
| ||
| directdensesolvers | Direct dense linear solvers | |
| directsparsesolvers | Direct sparse linear solvers | |
| iterativesparse | Sparse linear iterative solvers (GMRES) | |
| lincg | Sparse linear CG solver | |
| linlsqr | Sparse linear LSQR solver | |
| nleq | Solvers for nonlinear equations | |
| polynomialsolver | Polynomial solver | |
8.11
| ||
| airyf | Airy functions | |
| bessel | Bessel functions | |
| betaf | Beta function | |
| binomialdistr | Binomial distribution | |
| chebyshev | Chebyshev polynomials | |
| chisquaredistr | Chi-Square distribution | |
| dawson | Dawson integral | |
| elliptic | Elliptic integrals | |
| expintegrals | Exponential integrals | |
| fdistr | F-distribution | |
| fresnel | Fresnel integrals | |
| gammafunc | Gamma function | |
| hermite | Hermite polynomials | |
| ibetaf | Incomplete beta function | |
| igammaf | Incomplete gamma function | |
| jacobianelliptic | Jacobian elliptic functions | |
| laguerre | Laguerre polynomials | |
| legendre | Legendre polynomials | |
| normaldistr | Univarite and bivariate normal distribution PDF and CDF | |
| poissondistr | Poisson distribution | |
| psif | Psi function | |
| studenttdistr | Student's t-distribution | |
| trigintegrals | Trigonometric integrals | |
8.12
| ||
| basestat | Mean, variance, covariance, correlation, etc. | |
| correlationtests | Hypothesis testing: correlation tests | |
| jarquebera | Hypothesis testing: Jarque-Bera test | |
| mannwhitneyu | Hypothesis testing: Mann-Whitney-U test | |
| mcmc | Markov Chain Monte-Carlo | |
| stest | Hypothesis testing: sign test | |
| studentttests | Hypothesis testing: Student's t-test | |
| variancetests | Hypothesis testing: F-test and one-sample variance test | |
| wsr | Hypothesis testing: Wilcoxon signed rank test | |
ablas subpackage| ablas_d_gemm | Matrix multiplication (single-threaded) | |
| ablas_d_syrk | Symmetric rank-K update (single-threaded) |
cmatrixcopy function/************************************************************************* Copy Input parameters: M - number of rows N - number of columns A - source matrix, MxN submatrix is copied IA - submatrix offset (row index) JA - submatrix offset (column index) B - destination matrix, must be large enough to store result IB - submatrix offset (row index) JB - submatrix offset (column index) *************************************************************************/void cmatrixcopy(const ae_int_t m, const ae_int_t n, const complex_2d_array &a, const ae_int_t ia, const ae_int_t ja, complex_2d_array &b, const ae_int_t ib, const ae_int_t jb, const xparams _xparams = alglib::xdefault);
cmatrixgemm function/************************************************************************* This subroutine calculates C = alpha*op1(A)*op2(B) +beta*C where: * C is MxN general matrix * op1(A) is MxK matrix * op2(B) is KxN matrix * "op" may be identity transformation, transposition, conjugate transposition Additional info: * cache-oblivious algorithm is used. * multiplication result replaces C. If Beta=0, C elements are not used in calculations (not multiplied by zero - just not referenced) * if Alpha=0, A is not used (not multiplied by zero - just not referenced) * if both Beta and Alpha are zero, C is filled by zeros. IMPORTANT: This function does NOT preallocate output matrix C, it MUST be preallocated by caller prior to calling this function. In case C does not have enough space to store result, exception will be generated. INPUT PARAMETERS M - matrix size, M>0 N - matrix size, N>0 K - matrix size, K>0 Alpha - coefficient A - matrix IA - submatrix offset JA - submatrix offset OpTypeA - transformation type: * 0 - no transformation * 1 - transposition * 2 - conjugate transposition B - matrix IB - submatrix offset JB - submatrix offset OpTypeB - transformation type: * 0 - no transformation * 1 - transposition * 2 - conjugate transposition Beta - coefficient C - matrix (PREALLOCATED, large enough to store result) IC - submatrix offset JC - submatrix offset ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 2009-2019 Bochkanov Sergey *************************************************************************/void cmatrixgemm(const ae_int_t m, const ae_int_t n, const ae_int_t k, const alglib::complex alpha, const complex_2d_array &a, const ae_int_t ia, const ae_int_t ja, const ae_int_t optypea, const complex_2d_array &b, const ae_int_t ib, const ae_int_t jb, const ae_int_t optypeb, const alglib::complex beta, complex_2d_array &c, const ae_int_t ic, const ae_int_t jc, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixherk function/************************************************************************* This subroutine calculates C=alpha*A*A^H+beta*C or C=alpha*A^H*A+beta*C where: * C is NxN Hermitian matrix given by its upper/lower triangle * A is NxK matrix when A*A^H is calculated, KxN matrix otherwise Additional info: * multiplication result replaces C. If Beta=0, C elements are not used in calculations (not multiplied by zero - just not referenced) * if Alpha=0, A is not used (not multiplied by zero - just not referenced) * if both Beta and Alpha are zero, C is filled by zeros. INPUT PARAMETERS N - matrix size, N>=0 K - matrix size, K>=0 Alpha - coefficient A - matrix IA - submatrix offset (row index) JA - submatrix offset (column index) OpTypeA - multiplication type: * 0 - A*A^H is calculated * 2 - A^H*A is calculated Beta - coefficient C - preallocated input/output matrix IC - submatrix offset (row index) JC - submatrix offset (column index) IsUpper - whether upper or lower triangle of C is updated; this function updates only one half of C, leaving other half unchanged (not referenced at all). ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 16.12.2009-22.01.2018 Bochkanov Sergey *************************************************************************/void cmatrixherk(const ae_int_t n, const ae_int_t k, const double alpha, const complex_2d_array &a, const ae_int_t ia, const ae_int_t ja, const ae_int_t optypea, const double beta, complex_2d_array &c, const ae_int_t ic, const ae_int_t jc, const bool isupper, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixlefttrsm function/************************************************************************* This subroutine calculates op(A^-1)*X where: * X is MxN general matrix * A is MxM upper/lower triangular/unitriangular matrix * "op" may be identity transformation, transposition, conjugate transposition Multiplication result replaces X. INPUT PARAMETERS N - matrix size, N>=0 M - matrix size, N>=0 A - matrix, actial matrix is stored in A[I1:I1+M-1,J1:J1+M-1] I1 - submatrix offset J1 - submatrix offset IsUpper - whether matrix is upper triangular IsUnit - whether matrix is unitriangular OpType - transformation type: * 0 - no transformation * 1 - transposition * 2 - conjugate transposition X - matrix, actial matrix is stored in X[I2:I2+M-1,J2:J2+N-1] I2 - submatrix offset J2 - submatrix offset ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 15.12.2009-22.01.2018 Bochkanov Sergey *************************************************************************/void cmatrixlefttrsm(const ae_int_t m, const ae_int_t n, const complex_2d_array &a, const ae_int_t i1, const ae_int_t j1, const bool isupper, const bool isunit, const ae_int_t optype, complex_2d_array &x, const ae_int_t i2, const ae_int_t j2, const xparams _xparams = alglib::xdefault);
cmatrixmv function/************************************************************************* Matrix-vector product: y := op(A)*x INPUT PARAMETERS: M - number of rows of op(A) M>=0 N - number of columns of op(A) N>=0 A - target matrix IA - submatrix offset (row index) JA - submatrix offset (column index) OpA - operation type: * OpA=0 => op(A) = A * OpA=1 => op(A) = A^T * OpA=2 => op(A) = A^H X - input vector IX - subvector offset IY - subvector offset Y - preallocated matrix, must be large enough to store result OUTPUT PARAMETERS: Y - vector which stores result if M=0, then subroutine does nothing. if N=0, Y is filled by zeros. -- ALGLIB routine -- 28.01.2010 Bochkanov Sergey *************************************************************************/void cmatrixmv(const ae_int_t m, const ae_int_t n, const complex_2d_array &a, const ae_int_t ia, const ae_int_t ja, const ae_int_t opa, const complex_1d_array &x, const ae_int_t ix, complex_1d_array &y, const ae_int_t iy, const xparams _xparams = alglib::xdefault);
cmatrixrank1 function/************************************************************************* Rank-1 correction: A := A + u*v' INPUT PARAMETERS: M - number of rows N - number of columns A - target matrix, MxN submatrix is updated IA - submatrix offset (row index) JA - submatrix offset (column index) U - vector #1 IU - subvector offset V - vector #2 IV - subvector offset *************************************************************************/void cmatrixrank1(const ae_int_t m, const ae_int_t n, complex_2d_array &a, const ae_int_t ia, const ae_int_t ja, const complex_1d_array &u, const ae_int_t iu, const complex_1d_array &v, const ae_int_t iv, const xparams _xparams = alglib::xdefault);
cmatrixrighttrsm function/************************************************************************* This subroutine calculates X*op(A^-1) where: * X is MxN general matrix * A is NxN upper/lower triangular/unitriangular matrix * "op" may be identity transformation, transposition, conjugate transposition Multiplication result replaces X. INPUT PARAMETERS N - matrix size, N>=0 M - matrix size, N>=0 A - matrix, actial matrix is stored in A[I1:I1+N-1,J1:J1+N-1] I1 - submatrix offset J1 - submatrix offset IsUpper - whether matrix is upper triangular IsUnit - whether matrix is unitriangular OpType - transformation type: * 0 - no transformation * 1 - transposition * 2 - conjugate transposition X - matrix, actial matrix is stored in X[I2:I2+M-1,J2:J2+N-1] I2 - submatrix offset J2 - submatrix offset ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 20.01.2018 Bochkanov Sergey *************************************************************************/void cmatrixrighttrsm(const ae_int_t m, const ae_int_t n, const complex_2d_array &a, const ae_int_t i1, const ae_int_t j1, const bool isupper, const bool isunit, const ae_int_t optype, complex_2d_array &x, const ae_int_t i2, const ae_int_t j2, const xparams _xparams = alglib::xdefault);
cmatrixsyrk function/************************************************************************* This subroutine is an older version of CMatrixHERK(), one with wrong name (it is HErmitian update, not SYmmetric). It is left here for backward compatibility. -- ALGLIB routine -- 16.12.2009 Bochkanov Sergey *************************************************************************/void cmatrixsyrk(const ae_int_t n, const ae_int_t k, const double alpha, const complex_2d_array &a, const ae_int_t ia, const ae_int_t ja, const ae_int_t optypea, const double beta, complex_2d_array &c, const ae_int_t ic, const ae_int_t jc, const bool isupper, const xparams _xparams = alglib::xdefault);
cmatrixtranspose function/************************************************************************* Cache-oblivous complex "copy-and-transpose" Input parameters: M - number of rows N - number of columns A - source matrix, MxN submatrix is copied and transposed IA - submatrix offset (row index) JA - submatrix offset (column index) B - destination matrix, must be large enough to store result IB - submatrix offset (row index) JB - submatrix offset (column index) *************************************************************************/void cmatrixtranspose(const ae_int_t m, const ae_int_t n, const complex_2d_array &a, const ae_int_t ia, const ae_int_t ja, complex_2d_array &b, const ae_int_t ib, const ae_int_t jb, const xparams _xparams = alglib::xdefault);
rmatrixcopy function/************************************************************************* Copy Input parameters: M - number of rows N - number of columns A - source matrix, MxN submatrix is copied IA - submatrix offset (row index) JA - submatrix offset (column index) B - destination matrix, must be large enough to store result IB - submatrix offset (row index) JB - submatrix offset (column index) *************************************************************************/void rmatrixcopy(const ae_int_t m, const ae_int_t n, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, real_2d_array &b, const ae_int_t ib, const ae_int_t jb, const xparams _xparams = alglib::xdefault);
rmatrixenforcesymmetricity function/************************************************************************* This code enforces symmetricy of the matrix by copying Upper part to lower one (or vice versa). INPUT PARAMETERS: A - matrix N - number of rows/columns IsUpper - whether we want to copy upper triangle to lower one (True) or vice versa (False). *************************************************************************/void rmatrixenforcesymmetricity(real_2d_array &a, const ae_int_t n, const bool isupper, const xparams _xparams = alglib::xdefault);
rmatrixgemm function/************************************************************************* This subroutine calculates C = alpha*op1(A)*op2(B) +beta*C where: * C is MxN general matrix * op1(A) is MxK matrix * op2(B) is KxN matrix * "op" may be identity transformation, transposition Additional info: * cache-oblivious algorithm is used. * multiplication result replaces C. If Beta=0, C elements are not used in calculations (not multiplied by zero - just not referenced) * if Alpha=0, A is not used (not multiplied by zero - just not referenced) * if both Beta and Alpha are zero, C is filled by zeros. IMPORTANT: This function does NOT preallocate output matrix C, it MUST be preallocated by caller prior to calling this function. In case C does not have enough space to store result, exception will be generated. INPUT PARAMETERS M - matrix size, M>0 N - matrix size, N>0 K - matrix size, K>0 Alpha - coefficient A - matrix IA - submatrix offset JA - submatrix offset OpTypeA - transformation type: * 0 - no transformation * 1 - transposition B - matrix IB - submatrix offset JB - submatrix offset OpTypeB - transformation type: * 0 - no transformation * 1 - transposition Beta - coefficient C - PREALLOCATED output matrix, large enough to store result IC - submatrix offset JC - submatrix offset ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 2009-2019 Bochkanov Sergey *************************************************************************/void rmatrixgemm(const ae_int_t m, const ae_int_t n, const ae_int_t k, const double alpha, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const ae_int_t optypea, const real_2d_array &b, const ae_int_t ib, const ae_int_t jb, const ae_int_t optypeb, const double beta, real_2d_array &c, const ae_int_t ic, const ae_int_t jc, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixgemv function/************************************************************************* *************************************************************************/void rmatrixgemv(const ae_int_t m, const ae_int_t n, const double alpha, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const ae_int_t opa, const real_1d_array &x, const ae_int_t ix, const double beta, real_1d_array &y, const ae_int_t iy, const xparams _xparams = alglib::xdefault);
rmatrixgencopy function/************************************************************************* Performs generalized copy: B := Beta*B + Alpha*A. If Beta=0, then previous contents of B is simply ignored. If Alpha=0, then A is ignored and not referenced. If both Alpha and Beta are zero, B is filled by zeros. Input parameters: M - number of rows N - number of columns Alpha- coefficient A - source matrix, MxN submatrix is copied IA - submatrix offset (row index) JA - submatrix offset (column index) Beta- coefficient B - destination matrix, must be large enough to store result IB - submatrix offset (row index) JB - submatrix offset (column index) *************************************************************************/void rmatrixgencopy(const ae_int_t m, const ae_int_t n, const double alpha, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const double beta, real_2d_array &b, const ae_int_t ib, const ae_int_t jb, const xparams _xparams = alglib::xdefault);
rmatrixger function/************************************************************************* Rank-1 correction: A := A + alpha*u*v' NOTE: this function expects A to be large enough to store result. No automatic preallocation happens for smaller arrays. No integrity checks is performed for sizes of A, u, v. INPUT PARAMETERS: M - number of rows N - number of columns A - target matrix, MxN submatrix is updated IA - submatrix offset (row index) JA - submatrix offset (column index) Alpha- coefficient U - vector #1 IU - subvector offset V - vector #2 IV - subvector offset -- ALGLIB routine -- 16.10.2017 Bochkanov Sergey *************************************************************************/void rmatrixger(const ae_int_t m, const ae_int_t n, real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const double alpha, const real_1d_array &u, const ae_int_t iu, const real_1d_array &v, const ae_int_t iv, const xparams _xparams = alglib::xdefault);
rmatrixlefttrsm function/************************************************************************* This subroutine calculates op(A^-1)*X where: * X is MxN general matrix * A is MxM upper/lower triangular/unitriangular matrix * "op" may be identity transformation, transposition Multiplication result replaces X. INPUT PARAMETERS N - matrix size, N>=0 M - matrix size, N>=0 A - matrix, actial matrix is stored in A[I1:I1+M-1,J1:J1+M-1] I1 - submatrix offset J1 - submatrix offset IsUpper - whether matrix is upper triangular IsUnit - whether matrix is unitriangular OpType - transformation type: * 0 - no transformation * 1 - transposition X - matrix, actial matrix is stored in X[I2:I2+M-1,J2:J2+N-1] I2 - submatrix offset J2 - submatrix offset ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 15.12.2009-22.01.2018 Bochkanov Sergey *************************************************************************/void rmatrixlefttrsm(const ae_int_t m, const ae_int_t n, const real_2d_array &a, const ae_int_t i1, const ae_int_t j1, const bool isupper, const bool isunit, const ae_int_t optype, real_2d_array &x, const ae_int_t i2, const ae_int_t j2, const xparams _xparams = alglib::xdefault);
rmatrixmv function/************************************************************************* IMPORTANT: this function is deprecated since ALGLIB 3.13. Use RMatrixGEMV() which is more generic version of this function. Matrix-vector product: y := op(A)*x INPUT PARAMETERS: M - number of rows of op(A) N - number of columns of op(A) A - target matrix IA - submatrix offset (row index) JA - submatrix offset (column index) OpA - operation type: * OpA=0 => op(A) = A * OpA=1 => op(A) = A^T X - input vector IX - subvector offset IY - subvector offset Y - preallocated matrix, must be large enough to store result OUTPUT PARAMETERS: Y - vector which stores result if M=0, then subroutine does nothing. if N=0, Y is filled by zeros. -- ALGLIB routine -- 28.01.2010 Bochkanov Sergey *************************************************************************/void rmatrixmv(const ae_int_t m, const ae_int_t n, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const ae_int_t opa, const real_1d_array &x, const ae_int_t ix, real_1d_array &y, const ae_int_t iy, const xparams _xparams = alglib::xdefault);
rmatrixrank1 function/************************************************************************* IMPORTANT: this function is deprecated since ALGLIB 3.13. Use RMatrixGER() which is more generic version of this function. Rank-1 correction: A := A + u*v' INPUT PARAMETERS: M - number of rows N - number of columns A - target matrix, MxN submatrix is updated IA - submatrix offset (row index) JA - submatrix offset (column index) U - vector #1 IU - subvector offset V - vector #2 IV - subvector offset *************************************************************************/void rmatrixrank1(const ae_int_t m, const ae_int_t n, real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const real_1d_array &u, const ae_int_t iu, const real_1d_array &v, const ae_int_t iv, const xparams _xparams = alglib::xdefault);
rmatrixrighttrsm function/************************************************************************* This subroutine calculates X*op(A^-1) where: * X is MxN general matrix * A is NxN upper/lower triangular/unitriangular matrix * "op" may be identity transformation, transposition Multiplication result replaces X. INPUT PARAMETERS N - matrix size, N>=0 M - matrix size, N>=0 A - matrix, actial matrix is stored in A[I1:I1+N-1,J1:J1+N-1] I1 - submatrix offset J1 - submatrix offset IsUpper - whether matrix is upper triangular IsUnit - whether matrix is unitriangular OpType - transformation type: * 0 - no transformation * 1 - transposition X - matrix, actial matrix is stored in X[I2:I2+M-1,J2:J2+N-1] I2 - submatrix offset J2 - submatrix offset ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 15.12.2009-22.01.2018 Bochkanov Sergey *************************************************************************/void rmatrixrighttrsm(const ae_int_t m, const ae_int_t n, const real_2d_array &a, const ae_int_t i1, const ae_int_t j1, const bool isupper, const bool isunit, const ae_int_t optype, real_2d_array &x, const ae_int_t i2, const ae_int_t j2, const xparams _xparams = alglib::xdefault);
rmatrixsymv function/************************************************************************* *************************************************************************/void rmatrixsymv(const ae_int_t n, const double alpha, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const bool isupper, const real_1d_array &x, const ae_int_t ix, const double beta, real_1d_array &y, const ae_int_t iy, const xparams _xparams = alglib::xdefault);
rmatrixsyrk function/************************************************************************* This subroutine calculates C=alpha*A*A^T+beta*C or C=alpha*A^T*A+beta*C where: * C is NxN symmetric matrix given by its upper/lower triangle * A is NxK matrix when A*A^T is calculated, KxN matrix otherwise Additional info: * multiplication result replaces C. If Beta=0, C elements are not used in calculations (not multiplied by zero - just not referenced) * if Alpha=0, A is not used (not multiplied by zero - just not referenced) * if both Beta and Alpha are zero, C is filled by zeros. INPUT PARAMETERS N - matrix size, N>=0 K - matrix size, K>=0 Alpha - coefficient A - matrix IA - submatrix offset (row index) JA - submatrix offset (column index) OpTypeA - multiplication type: * 0 - A*A^T is calculated * 2 - A^T*A is calculated Beta - coefficient C - preallocated input/output matrix IC - submatrix offset (row index) JC - submatrix offset (column index) IsUpper - whether C is upper triangular or lower triangular ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 16.12.2009-22.01.2018 Bochkanov Sergey *************************************************************************/void rmatrixsyrk(const ae_int_t n, const ae_int_t k, const double alpha, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const ae_int_t optypea, const double beta, real_2d_array &c, const ae_int_t ic, const ae_int_t jc, const bool isupper, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixsyvmv function/************************************************************************* *************************************************************************/double rmatrixsyvmv(const ae_int_t n, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const bool isupper, const real_1d_array &x, const ae_int_t ix, real_1d_array &tmp, const xparams _xparams = alglib::xdefault);
rmatrixtranspose function/************************************************************************* Cache-oblivous real "copy-and-transpose" Input parameters: M - number of rows N - number of columns A - source matrix, MxN submatrix is copied and transposed IA - submatrix offset (row index) JA - submatrix offset (column index) B - destination matrix, must be large enough to store result IB - submatrix offset (row index) JB - submatrix offset (column index) *************************************************************************/void rmatrixtranspose(const ae_int_t m, const ae_int_t n, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, real_2d_array &b, const ae_int_t ib, const ae_int_t jb, const xparams _xparams = alglib::xdefault);
rmatrixtrsv function/************************************************************************* This subroutine solves linear system op(A)*x=b where: * A is NxN upper/lower triangular/unitriangular matrix * X and B are Nx1 vectors * "op" may be identity transformation or transposition Solution replaces X. IMPORTANT: * no overflow/underflow/denegeracy tests is performed. * no integrity checks for operand sizes, out-of-bounds accesses and so on is performed INPUT PARAMETERS N - matrix size, N>=0 A - matrix, actial matrix is stored in A[IA:IA+N-1,JA:JA+N-1] IA - submatrix offset JA - submatrix offset IsUpper - whether matrix is upper triangular IsUnit - whether matrix is unitriangular OpType - transformation type: * 0 - no transformation * 1 - transposition X - right part, actual vector is stored in X[IX:IX+N-1] IX - offset OUTPUT PARAMETERS X - solution replaces elements X[IX:IX+N-1] -- ALGLIB routine / remastering of LAPACK's DTRSV -- (c) 2017 Bochkanov Sergey - converted to ALGLIB (c) 2016 Reference BLAS level1 routine (LAPACK version 3.7.0) Reference BLAS is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd. *************************************************************************/void rmatrixtrsv(const ae_int_t n, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const bool isupper, const bool isunit, const ae_int_t optype, real_1d_array &x, const ae_int_t ix, const xparams _xparams = alglib::xdefault);
rvectorcopy function/************************************************************************* Copy Input parameters: N - subvector size A - source vector, N elements are copied IA - source offset (first element index) B - destination vector, must be large enough to store result IB - destination offset (first element index) *************************************************************************/void rvectorcopy(const ae_int_t n, const real_1d_array &a, const ae_int_t ia, real_1d_array &b, const ae_int_t ib, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
real_2d_array a = "[[2,1],[1,3]]";
real_2d_array b = "[[2,1],[0,1]]";
real_2d_array c = "[[0,0],[0,0]]";
//
// rmatrixgemm() function allows us to calculate matrix product C:=A*B or
// to perform more general operation, C:=alpha*op1(A)*op2(B)+beta*C,
// where A, B, C are rectangular matrices, op(X) can be X or X^T,
// alpha and beta are scalars.
//
// This function:
// * can apply transposition and/or multiplication by scalar to operands
// * can use arbitrary part of matrices A/B (given by submatrix offset)
// * can store result into arbitrary part of C
// * for performance reasons requires C to be preallocated
//
// Parameters of this function are:
// * M, N, K - sizes of op1(A) (which is MxK), op2(B) (which
// is KxN) and C (which is MxN)
// * Alpha - coefficient before A*B
// * A, IA, JA - matrix A and offset of the submatrix
// * OpTypeA - transformation type:
// 0 - no transformation
// 1 - transposition
// * B, IB, JB - matrix B and offset of the submatrix
// * OpTypeB - transformation type:
// 0 - no transformation
// 1 - transposition
// * Beta - coefficient before C
// * C, IC, JC - preallocated matrix C and offset of the submatrix
//
// Below we perform simple product C:=A*B (alpha=1, beta=0)
//
// IMPORTANT: this function works with preallocated C, which must be large
// enough to store multiplication result.
//
ae_int_t m = 2;
ae_int_t n = 2;
ae_int_t k = 2;
double alpha = 1.0;
ae_int_t ia = 0;
ae_int_t ja = 0;
ae_int_t optypea = 0;
ae_int_t ib = 0;
ae_int_t jb = 0;
ae_int_t optypeb = 0;
double beta = 0.0;
ae_int_t ic = 0;
ae_int_t jc = 0;
rmatrixgemm(m, n, k, alpha, a, ia, ja, optypea, b, ib, jb, optypeb, beta, c, ic, jc);
printf("%s\n", c.tostring(3).c_str()); // EXPECTED: [[4,3],[2,4]]
//
// Now we try to apply some simple transformation to operands: C:=A*B^T
//
optypeb = 1;
rmatrixgemm(m, n, k, alpha, a, ia, ja, optypea, b, ib, jb, optypeb, beta, c, ic, jc);
printf("%s\n", c.tostring(3).c_str()); // EXPECTED: [[5,1],[5,3]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// rmatrixsyrk() function allows us to calculate symmetric rank-K update
// C := beta*C + alpha*A'*A, where C is square N*N matrix, A is square K*N
// matrix, alpha and beta are scalars. It is also possible to update by
// adding A*A' instead of A'*A.
//
// Parameters of this function are:
// * N, K - matrix size
// * Alpha - coefficient before A
// * A, IA, JA - matrix and submatrix offsets
// * OpTypeA - multiplication type:
// * 0 - A*A^T is calculated
// * 2 - A^T*A is calculated
// * Beta - coefficient before C
// * C, IC, JC - preallocated input/output matrix and submatrix offsets
// * IsUpper - whether upper or lower triangle of C is updated;
// this function updates only one half of C, leaving
// other half unchanged (not referenced at all).
//
// Below we will show how to calculate simple product C:=A'*A
//
// NOTE: beta=0 and we do not use previous value of C, but still it
// MUST be preallocated.
//
ae_int_t n = 2;
ae_int_t k = 1;
double alpha = 1.0;
ae_int_t ia = 0;
ae_int_t ja = 0;
ae_int_t optypea = 2;
double beta = 0.0;
ae_int_t ic = 0;
ae_int_t jc = 0;
bool isupper = true;
real_2d_array a = "[[1,2]]";
// preallocate space to store result
real_2d_array c = "[[0,0],[0,0]]";
// calculate product, store result into upper part of c
rmatrixsyrk(n, k, alpha, a, ia, ja, optypea, beta, c, ic, jc, isupper);
// output result.
// IMPORTANT: lower triangle of C was NOT updated!
printf("%s\n", c.tostring(3).c_str()); // EXPECTED: [[1,2],[0,4]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
airyf subpackageairy function/************************************************************************* Airy function Solution of the differential equation y"(x) = xy. The function returns the two independent solutions Ai, Bi and their first derivatives Ai'(x), Bi'(x). Evaluation is by power series summation for small x, by rational minimax approximations for large x. ACCURACY: Error criterion is absolute when function <= 1, relative when function > 1, except * denotes relative error criterion. For large negative x, the absolute error increases as x^1.5. For large positive x, the relative error increases as x^1.5. Arithmetic domain function # trials peak rms IEEE -10, 0 Ai 10000 1.6e-15 2.7e-16 IEEE 0, 10 Ai 10000 2.3e-14* 1.8e-15* IEEE -10, 0 Ai' 10000 4.6e-15 7.6e-16 IEEE 0, 10 Ai' 10000 1.8e-14* 1.5e-15* IEEE -10, 10 Bi 30000 4.2e-15 5.3e-16 IEEE -10, 10 Bi' 30000 4.9e-15 7.3e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier *************************************************************************/void airy(const double x, double &ai, double &aip, double &bi, double &bip, const xparams _xparams = alglib::xdefault);
autogk subpackage| autogk_d1 | Integrating f=exp(x) by adaptive integrator |
autogkreport class/************************************************************************* Integration report: * TerminationType = completetion code: * -5 non-convergence of Gauss-Kronrod nodes calculation subroutine. * -1 incorrect parameters were specified * 1 OK * Rep.NFEV countains number of function calculations * Rep.NIntervals contains number of intervals [a,b] was partitioned into. *************************************************************************/class autogkreport { public: autogkreport(); autogkreport(const autogkreport &rhs); autogkreport& operator=(const autogkreport &rhs); virtual ~autogkreport(); ae_int_t terminationtype; ae_int_t nfev; ae_int_t nintervals; };
autogkstate class/************************************************************************* This structure stores state of the integration algorithm. Although this class has public fields, they are not intended for external use. You should use ALGLIB functions to work with this class: * autogksmooth()/AutoGKSmoothW()/... to create objects * autogkintegrate() to begin integration * autogkresults() to get results *************************************************************************/class autogkstate { public: autogkstate(); autogkstate(const autogkstate &rhs); autogkstate& operator=(const autogkstate &rhs); virtual ~autogkstate(); };
autogkintegrate function/************************************************************************* This function is used to start iterations of the 1-dimensional integrator It accepts following parameters: func - callback which calculates f(x) for given x ptr - optional pointer which is passed to func; can be NULL -- ALGLIB -- Copyright 07.05.2009 by Bochkanov Sergey *************************************************************************/void autogkintegrate(autogkstate &state, void (*func)(double x, double xminusa, double bminusx, double &y, void *ptr), void *ptr = NULL, const xparams _xparams = alglib::xdefault);
Examples: [1]
autogkiteration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool autogkiteration(autogkstate &state, const xparams _xparams = alglib::xdefault);
autogkresults function/************************************************************************* Adaptive integration results Called after AutoGKIteration returned False. Input parameters: State - algorithm state (used by AutoGKIteration). Output parameters: V - integral(f(x)dx,a,b) Rep - optimization report (see AutoGKReport description) -- ALGLIB -- Copyright 14.11.2007 by Bochkanov Sergey *************************************************************************/void autogkresults(const autogkstate &state, double &v, autogkreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
autogksingular function/************************************************************************* Integration on a finite interval [A,B]. Integrand have integrable singularities at A/B. F(X) must diverge as "(x-A)^alpha" at A, as "(B-x)^beta" at B, with known alpha/beta (alpha>-1, beta>-1). If alpha/beta are not known, estimates from below can be used (but these estimates should be greater than -1 too). One of alpha/beta variables (or even both alpha/beta) may be equal to 0, which means than function F(x) is non-singular at A/B. Anyway (singular at bounds or not), function F(x) is supposed to be continuous on (A,B). Fast-convergent algorithm based on a Gauss-Kronrod formula is used. Result is calculated with accuracy close to the machine precision. INPUT PARAMETERS: A, B - interval boundaries (A<B, A=B or A>B) Alpha - power-law coefficient of the F(x) at A, Alpha>-1 Beta - power-law coefficient of the F(x) at B, Beta>-1 OUTPUT PARAMETERS State - structure which stores algorithm state SEE ALSO AutoGKSmooth, AutoGKSmoothW, AutoGKResults. -- ALGLIB -- Copyright 06.05.2009 by Bochkanov Sergey *************************************************************************/void autogksingular(const double a, const double b, const double alpha, const double beta, autogkstate &state, const xparams _xparams = alglib::xdefault);
autogksmooth function/************************************************************************* Integration of a smooth function F(x) on a finite interval [a,b]. Fast-convergent algorithm based on a Gauss-Kronrod formula is used. Result is calculated with accuracy close to the machine precision. Algorithm works well only with smooth integrands. It may be used with continuous non-smooth integrands, but with less performance. It should never be used with integrands which have integrable singularities at lower or upper limits - algorithm may crash. Use AutoGKSingular in such cases. INPUT PARAMETERS: A, B - interval boundaries (A<B, A=B or A>B) OUTPUT PARAMETERS State - structure which stores algorithm state SEE ALSO AutoGKSmoothW, AutoGKSingular, AutoGKResults. -- ALGLIB -- Copyright 06.05.2009 by Bochkanov Sergey *************************************************************************/void autogksmooth(const double a, const double b, autogkstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
autogksmoothw function/************************************************************************* Integration of a smooth function F(x) on a finite interval [a,b]. This subroutine is same as AutoGKSmooth(), but it guarantees that interval [a,b] is partitioned into subintervals which have width at most XWidth. Subroutine can be used when integrating nearly-constant function with narrow "bumps" (about XWidth wide). If "bumps" are too narrow, AutoGKSmooth subroutine can overlook them. INPUT PARAMETERS: A, B - interval boundaries (A<B, A=B or A>B) OUTPUT PARAMETERS State - structure which stores algorithm state SEE ALSO AutoGKSmooth, AutoGKSingular, AutoGKResults. -- ALGLIB -- Copyright 06.05.2009 by Bochkanov Sergey *************************************************************************/void autogksmoothw(const double a, const double b, const double xwidth, autogkstate &state, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "integration.h"
using namespace alglib;
void int_function_1_func(double x, double xminusa, double bminusx, double &y, void *ptr)
{
// this callback calculates f(x)=exp(x)
y = exp(x);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates integration of f=exp(x) on [0,1]:
// * first, autogkstate is initialized
// * then we call integration function
// * and finally we obtain results with autogkresults() call
//
double a = 0;
double b = 1;
autogkstate s;
double v;
autogkreport rep;
autogksmooth(a, b, s);
alglib::autogkintegrate(s, int_function_1_func);
autogkresults(s, v, rep);
printf("%.2f\n", double(v)); // EXPECTED: 1.7182
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
basestat subpackage| basestat_d_base | Basic functionality (moments, adev, median, percentile) | |
| basestat_d_c2 | Correlation (covariance) between two random variables | |
| basestat_d_cm | Correlation (covariance) between components of random vector | |
| basestat_d_cm2 | Correlation (covariance) between two random vectors |
cov2 function/************************************************************************* 2-sample covariance Input parameters: X - sample 1 (array indexes: [0..N-1]) Y - sample 2 (array indexes: [0..N-1]) N - N>=0, sample size: * if given, only N leading elements of X/Y are processed * if not given, automatically determined from input sizes Result: covariance (zero for N=0 or N=1) -- ALGLIB -- Copyright 28.10.2010 by Bochkanov Sergey *************************************************************************/double cov2(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const xparams _xparams = alglib::xdefault); double cov2(const real_1d_array &x, const real_1d_array &y, const xparams _xparams = alglib::xdefault);
Examples: [1]
covm function/************************************************************************* Covariance matrix ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: X - array[N,M], sample matrix: * J-th column corresponds to J-th variable * I-th row corresponds to I-th observation N - N>=0, number of observations: * if given, only leading N rows of X are used * if not given, automatically determined from input size M - M>0, number of variables: * if given, only leading M columns of X are used * if not given, automatically determined from input size OUTPUT PARAMETERS: C - array[M,M], covariance matrix (zero if N=0 or N=1) -- ALGLIB -- Copyright 28.10.2010 by Bochkanov Sergey *************************************************************************/void covm(const real_2d_array &x, const ae_int_t n, const ae_int_t m, real_2d_array &c, const xparams _xparams = alglib::xdefault); void covm(const real_2d_array &x, real_2d_array &c, const xparams _xparams = alglib::xdefault);
Examples: [1]
covm2 function/************************************************************************* Cross-covariance matrix ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: X - array[N,M1], sample matrix: * J-th column corresponds to J-th variable * I-th row corresponds to I-th observation Y - array[N,M2], sample matrix: * J-th column corresponds to J-th variable * I-th row corresponds to I-th observation N - N>=0, number of observations: * if given, only leading N rows of X/Y are used * if not given, automatically determined from input sizes M1 - M1>0, number of variables in X: * if given, only leading M1 columns of X are used * if not given, automatically determined from input size M2 - M2>0, number of variables in Y: * if given, only leading M1 columns of X are used * if not given, automatically determined from input size OUTPUT PARAMETERS: C - array[M1,M2], cross-covariance matrix (zero if N=0 or N=1) -- ALGLIB -- Copyright 28.10.2010 by Bochkanov Sergey *************************************************************************/void covm2(const real_2d_array &x, const real_2d_array &y, const ae_int_t n, const ae_int_t m1, const ae_int_t m2, real_2d_array &c, const xparams _xparams = alglib::xdefault); void covm2(const real_2d_array &x, const real_2d_array &y, real_2d_array &c, const xparams _xparams = alglib::xdefault);
Examples: [1]
pearsoncorr2 function/************************************************************************* Pearson product-moment correlation coefficient Input parameters: X - sample 1 (array indexes: [0..N-1]) Y - sample 2 (array indexes: [0..N-1]) N - N>=0, sample size: * if given, only N leading elements of X/Y are processed * if not given, automatically determined from input sizes Result: Pearson product-moment correlation coefficient (zero for N=0 or N=1) -- ALGLIB -- Copyright 28.10.2010 by Bochkanov Sergey *************************************************************************/double pearsoncorr2(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const xparams _xparams = alglib::xdefault); double pearsoncorr2(const real_1d_array &x, const real_1d_array &y, const xparams _xparams = alglib::xdefault);
Examples: [1]
pearsoncorrelation function/************************************************************************* Obsolete function, we recommend to use PearsonCorr2(). -- ALGLIB -- Copyright 09.04.2007 by Bochkanov Sergey *************************************************************************/double pearsoncorrelation(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const xparams _xparams = alglib::xdefault);
pearsoncorrm function/************************************************************************* Pearson product-moment correlation matrix ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: X - array[N,M], sample matrix: * J-th column corresponds to J-th variable * I-th row corresponds to I-th observation N - N>=0, number of observations: * if given, only leading N rows of X are used * if not given, automatically determined from input size M - M>0, number of variables: * if given, only leading M columns of X are used * if not given, automatically determined from input size OUTPUT PARAMETERS: C - array[M,M], correlation matrix (zero if N=0 or N=1) -- ALGLIB -- Copyright 28.10.2010 by Bochkanov Sergey *************************************************************************/void pearsoncorrm(const real_2d_array &x, const ae_int_t n, const ae_int_t m, real_2d_array &c, const xparams _xparams = alglib::xdefault); void pearsoncorrm(const real_2d_array &x, real_2d_array &c, const xparams _xparams = alglib::xdefault);
Examples: [1]
pearsoncorrm2 function/************************************************************************* Pearson product-moment cross-correlation matrix ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: X - array[N,M1], sample matrix: * J-th column corresponds to J-th variable * I-th row corresponds to I-th observation Y - array[N,M2], sample matrix: * J-th column corresponds to J-th variable * I-th row corresponds to I-th observation N - N>=0, number of observations: * if given, only leading N rows of X/Y are used * if not given, automatically determined from input sizes M1 - M1>0, number of variables in X: * if given, only leading M1 columns of X are used * if not given, automatically determined from input size M2 - M2>0, number of variables in Y: * if given, only leading M1 columns of X are used * if not given, automatically determined from input size OUTPUT PARAMETERS: C - array[M1,M2], cross-correlation matrix (zero if N=0 or N=1) -- ALGLIB -- Copyright 28.10.2010 by Bochkanov Sergey *************************************************************************/void pearsoncorrm2(const real_2d_array &x, const real_2d_array &y, const ae_int_t n, const ae_int_t m1, const ae_int_t m2, real_2d_array &c, const xparams _xparams = alglib::xdefault); void pearsoncorrm2(const real_2d_array &x, const real_2d_array &y, real_2d_array &c, const xparams _xparams = alglib::xdefault);
Examples: [1]
rankdata function/************************************************************************* This function replaces data in XY by their ranks: * XY is processed row-by-row * rows are processed separately * tied data are correctly handled (tied ranks are calculated) * ranking starts from 0, ends at NFeatures-1 * sum of within-row values is equal to (NFeatures-1)*NFeatures/2 ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: XY - array[NPoints,NFeatures], dataset NPoints - number of points NFeatures- number of features OUTPUT PARAMETERS: XY - data are replaced by their within-row ranks; ranking starts from 0, ends at NFeatures-1 -- ALGLIB -- Copyright 18.04.2013 by Bochkanov Sergey *************************************************************************/void rankdata(real_2d_array &xy, const ae_int_t npoints, const ae_int_t nfeatures, const xparams _xparams = alglib::xdefault); void rankdata(real_2d_array &xy, const xparams _xparams = alglib::xdefault);
rankdatacentered function/************************************************************************* This function replaces data in XY by their CENTERED ranks: * XY is processed row-by-row * rows are processed separately * tied data are correctly handled (tied ranks are calculated) * centered ranks are just usual ranks, but centered in such way that sum of within-row values is equal to 0.0. * centering is performed by subtracting mean from each row, i.e it changes mean value, but does NOT change higher moments ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: XY - array[NPoints,NFeatures], dataset NPoints - number of points NFeatures- number of features OUTPUT PARAMETERS: XY - data are replaced by their within-row ranks; ranking starts from 0, ends at NFeatures-1 -- ALGLIB -- Copyright 18.04.2013 by Bochkanov Sergey *************************************************************************/void rankdatacentered(real_2d_array &xy, const ae_int_t npoints, const ae_int_t nfeatures, const xparams _xparams = alglib::xdefault); void rankdatacentered(real_2d_array &xy, const xparams _xparams = alglib::xdefault);
sampleadev function/************************************************************************* ADev Input parameters: X - sample N - N>=0, sample size: * if given, only leading N elements of X are processed * if not given, automatically determined from size of X Output parameters: ADev- ADev -- ALGLIB -- Copyright 06.09.2006 by Bochkanov Sergey *************************************************************************/void sampleadev(const real_1d_array &x, const ae_int_t n, double &adev, const xparams _xparams = alglib::xdefault); void sampleadev(const real_1d_array &x, double &adev, const xparams _xparams = alglib::xdefault);
Examples: [1]
samplekurtosis function/************************************************************************* Calculation of the kurtosis. INPUT PARAMETERS: X - sample N - N>=0, sample size: * if given, only leading N elements of X are processed * if not given, automatically determined from size of X NOTE: This function return result which calculated by 'SampleMoments' function and stored at 'Kurtosis' variable. -- ALGLIB -- Copyright 06.09.2006 by Bochkanov Sergey *************************************************************************/double samplekurtosis(const real_1d_array &x, const ae_int_t n, const xparams _xparams = alglib::xdefault); double samplekurtosis(const real_1d_array &x, const xparams _xparams = alglib::xdefault);
samplemean function/************************************************************************* Calculation of the mean. INPUT PARAMETERS: X - sample N - N>=0, sample size: * if given, only leading N elements of X are processed * if not given, automatically determined from size of X NOTE: This function return result which calculated by 'SampleMoments' function and stored at 'Mean' variable. -- ALGLIB -- Copyright 06.09.2006 by Bochkanov Sergey *************************************************************************/double samplemean(const real_1d_array &x, const ae_int_t n, const xparams _xparams = alglib::xdefault); double samplemean(const real_1d_array &x, const xparams _xparams = alglib::xdefault);
samplemedian function/************************************************************************* Median calculation. Input parameters: X - sample (array indexes: [0..N-1]) N - N>=0, sample size: * if given, only leading N elements of X are processed * if not given, automatically determined from size of X Output parameters: Median -- ALGLIB -- Copyright 06.09.2006 by Bochkanov Sergey *************************************************************************/void samplemedian(const real_1d_array &x, const ae_int_t n, double &median, const xparams _xparams = alglib::xdefault); void samplemedian(const real_1d_array &x, double &median, const xparams _xparams = alglib::xdefault);
Examples: [1]
samplemoments function/************************************************************************* Calculation of the distribution moments: mean, variance, skewness, kurtosis. INPUT PARAMETERS: X - sample N - N>=0, sample size: * if given, only leading N elements of X are processed * if not given, automatically determined from size of X OUTPUT PARAMETERS Mean - mean. Variance- variance. Skewness- skewness (if variance<>0; zero otherwise). Kurtosis- kurtosis (if variance<>0; zero otherwise). NOTE: variance is calculated by dividing sum of squares by N-1, not N. -- ALGLIB -- Copyright 06.09.2006 by Bochkanov Sergey *************************************************************************/void samplemoments(const real_1d_array &x, const ae_int_t n, double &mean, double &variance, double &skewness, double &kurtosis, const xparams _xparams = alglib::xdefault); void samplemoments(const real_1d_array &x, double &mean, double &variance, double &skewness, double &kurtosis, const xparams _xparams = alglib::xdefault);
Examples: [1]
samplepercentile function/************************************************************************* Percentile calculation. Input parameters: X - sample (array indexes: [0..N-1]) N - N>=0, sample size: * if given, only leading N elements of X are processed * if not given, automatically determined from size of X P - percentile (0<=P<=1) Output parameters: V - percentile -- ALGLIB -- Copyright 01.03.2008 by Bochkanov Sergey *************************************************************************/void samplepercentile(const real_1d_array &x, const ae_int_t n, const double p, double &v, const xparams _xparams = alglib::xdefault); void samplepercentile(const real_1d_array &x, const double p, double &v, const xparams _xparams = alglib::xdefault);
Examples: [1]
sampleskewness function/************************************************************************* Calculation of the skewness. INPUT PARAMETERS: X - sample N - N>=0, sample size: * if given, only leading N elements of X are processed * if not given, automatically determined from size of X NOTE: This function return result which calculated by 'SampleMoments' function and stored at 'Skewness' variable. -- ALGLIB -- Copyright 06.09.2006 by Bochkanov Sergey *************************************************************************/double sampleskewness(const real_1d_array &x, const ae_int_t n, const xparams _xparams = alglib::xdefault); double sampleskewness(const real_1d_array &x, const xparams _xparams = alglib::xdefault);
samplevariance function/************************************************************************* Calculation of the variance. INPUT PARAMETERS: X - sample N - N>=0, sample size: * if given, only leading N elements of X are processed * if not given, automatically determined from size of X NOTE: This function return result which calculated by 'SampleMoments' function and stored at 'Variance' variable. -- ALGLIB -- Copyright 06.09.2006 by Bochkanov Sergey *************************************************************************/double samplevariance(const real_1d_array &x, const ae_int_t n, const xparams _xparams = alglib::xdefault); double samplevariance(const real_1d_array &x, const xparams _xparams = alglib::xdefault);
spearmancorr2 function/************************************************************************* Spearman's rank correlation coefficient Input parameters: X - sample 1 (array indexes: [0..N-1]) Y - sample 2 (array indexes: [0..N-1]) N - N>=0, sample size: * if given, only N leading elements of X/Y are processed * if not given, automatically determined from input sizes Result: Spearman's rank correlation coefficient (zero for N=0 or N=1) -- ALGLIB -- Copyright 09.04.2007 by Bochkanov Sergey *************************************************************************/double spearmancorr2(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const xparams _xparams = alglib::xdefault); double spearmancorr2(const real_1d_array &x, const real_1d_array &y, const xparams _xparams = alglib::xdefault);
Examples: [1]
spearmancorrm function/************************************************************************* Spearman's rank correlation matrix ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: X - array[N,M], sample matrix: * J-th column corresponds to J-th variable * I-th row corresponds to I-th observation N - N>=0, number of observations: * if given, only leading N rows of X are used * if not given, automatically determined from input size M - M>0, number of variables: * if given, only leading M columns of X are used * if not given, automatically determined from input size OUTPUT PARAMETERS: C - array[M,M], correlation matrix (zero if N=0 or N=1) -- ALGLIB -- Copyright 28.10.2010 by Bochkanov Sergey *************************************************************************/void spearmancorrm(const real_2d_array &x, const ae_int_t n, const ae_int_t m, real_2d_array &c, const xparams _xparams = alglib::xdefault); void spearmancorrm(const real_2d_array &x, real_2d_array &c, const xparams _xparams = alglib::xdefault);
Examples: [1]
spearmancorrm2 function/************************************************************************* Spearman's rank cross-correlation matrix ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: X - array[N,M1], sample matrix: * J-th column corresponds to J-th variable * I-th row corresponds to I-th observation Y - array[N,M2], sample matrix: * J-th column corresponds to J-th variable * I-th row corresponds to I-th observation N - N>=0, number of observations: * if given, only leading N rows of X/Y are used * if not given, automatically determined from input sizes M1 - M1>0, number of variables in X: * if given, only leading M1 columns of X are used * if not given, automatically determined from input size M2 - M2>0, number of variables in Y: * if given, only leading M1 columns of X are used * if not given, automatically determined from input size OUTPUT PARAMETERS: C - array[M1,M2], cross-correlation matrix (zero if N=0 or N=1) -- ALGLIB -- Copyright 28.10.2010 by Bochkanov Sergey *************************************************************************/void spearmancorrm2(const real_2d_array &x, const real_2d_array &y, const ae_int_t n, const ae_int_t m1, const ae_int_t m2, real_2d_array &c, const xparams _xparams = alglib::xdefault); void spearmancorrm2(const real_2d_array &x, const real_2d_array &y, real_2d_array &c, const xparams _xparams = alglib::xdefault);
Examples: [1]
spearmanrankcorrelation function/************************************************************************* Obsolete function, we recommend to use SpearmanCorr2(). -- ALGLIB -- Copyright 09.04.2007 by Bochkanov Sergey *************************************************************************/double spearmanrankcorrelation(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "statistics.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
real_1d_array x = "[0,1,4,9,16,25,36,49,64,81]";
double mean;
double variance;
double skewness;
double kurtosis;
double adev;
double p;
double v;
//
// Here we demonstrate calculation of sample moments
// (mean, variance, skewness, kurtosis)
//
samplemoments(x, mean, variance, skewness, kurtosis);
printf("%.1f\n", double(mean)); // EXPECTED: 28.5
printf("%.1f\n", double(variance)); // EXPECTED: 801.1667
printf("%.1f\n", double(skewness)); // EXPECTED: 0.5751
printf("%.1f\n", double(kurtosis)); // EXPECTED: -1.2666
//
// Average deviation
//
sampleadev(x, adev);
printf("%.1f\n", double(adev)); // EXPECTED: 23.2
//
// Median and percentile
//
samplemedian(x, v);
printf("%.1f\n", double(v)); // EXPECTED: 20.5
p = 0.5;
samplepercentile(x, p, v);
printf("%.1f\n", double(v)); // EXPECTED: 20.5
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "statistics.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// We have two samples - x and y, and want to measure dependency between them
//
real_1d_array x = "[0,1,4,9,16,25,36,49,64,81]";
real_1d_array y = "[0,1,2,3,4,5,6,7,8,9]";
double v;
//
// Three dependency measures are calculated:
// * covariation
// * Pearson correlation
// * Spearman rank correlation
//
v = cov2(x, y);
printf("%.2f\n", double(v)); // EXPECTED: 82.5
v = pearsoncorr2(x, y);
printf("%.2f\n", double(v)); // EXPECTED: 0.9627
v = spearmancorr2(x, y);
printf("%.2f\n", double(v)); // EXPECTED: 1.000
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "statistics.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// X is a sample matrix:
// * I-th row corresponds to I-th observation
// * J-th column corresponds to J-th variable
//
real_2d_array x = "[[1,0,1],[1,1,0],[-1,1,0],[-2,-1,1],[-1,0,9]]";
real_2d_array c;
//
// Three dependency measures are calculated:
// * covariation
// * Pearson correlation
// * Spearman rank correlation
//
// Result is stored into C, with C[i,j] equal to correlation
// (covariance) between I-th and J-th variables of X.
//
covm(x, c);
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [[1.80,0.60,-1.40],[0.60,0.70,-0.80],[-1.40,-0.80,14.70]]
pearsoncorrm(x, c);
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [[1.000,0.535,-0.272],[0.535,1.000,-0.249],[-0.272,-0.249,1.000]]
spearmancorrm(x, c);
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [[1.000,0.556,-0.306],[0.556,1.000,-0.750],[-0.306,-0.750,1.000]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "statistics.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// X and Y are sample matrices:
// * I-th row corresponds to I-th observation
// * J-th column corresponds to J-th variable
//
real_2d_array x = "[[1,0,1],[1,1,0],[-1,1,0],[-2,-1,1],[-1,0,9]]";
real_2d_array y = "[[2,3],[2,1],[-1,6],[-9,9],[7,1]]";
real_2d_array c;
//
// Three dependency measures are calculated:
// * covariation
// * Pearson correlation
// * Spearman rank correlation
//
// Result is stored into C, with C[i,j] equal to correlation
// (covariance) between I-th variable of X and J-th variable of Y.
//
covm2(x, y, c);
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [[4.100,-3.250],[2.450,-1.500],[13.450,-5.750]]
pearsoncorrm2(x, y, c);
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [[0.519,-0.699],[0.497,-0.518],[0.596,-0.433]]
spearmancorrm2(x, y, c);
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [[0.541,-0.649],[0.216,-0.433],[0.433,-0.135]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
bdss subpackagedsoptimalsplit2 function/************************************************************************* Optimal binary classification Algorithms finds optimal (=with minimal cross-entropy) binary partition. Internal subroutine. INPUT PARAMETERS: A - array[0..N-1], variable C - array[0..N-1], class numbers (0 or 1). N - array size OUTPUT PARAMETERS: Info - completetion code: * -3, all values of A[] are same (partition is impossible) * -2, one of C[] is incorrect (<0, >1) * -1, incorrect pararemets were passed (N<=0). * 1, OK Threshold- partiton boundary. Left part contains values which are strictly less than Threshold. Right part contains values which are greater than or equal to Threshold. PAL, PBL- probabilities P(0|v<Threshold) and P(1|v<Threshold) PAR, PBR- probabilities P(0|v>=Threshold) and P(1|v>=Threshold) CVE - cross-validation estimate of cross-entropy -- ALGLIB -- Copyright 22.05.2008 by Bochkanov Sergey *************************************************************************/void dsoptimalsplit2(const real_1d_array &a, const integer_1d_array &c, const ae_int_t n, ae_int_t &info, double &threshold, double &pal, double &pbl, double &par, double &pbr, double &cve, const xparams _xparams = alglib::xdefault);
dsoptimalsplit2fast function/************************************************************************* Optimal partition, internal subroutine. Fast version. Accepts: A array[0..N-1] array of attributes array[0..N-1] C array[0..N-1] array of class labels TiesBuf array[0..N] temporaries (ties) CntBuf array[0..2*NC-1] temporaries (counts) Alpha centering factor (0<=alpha<=1, recommended value - 0.05) BufR array[0..N-1] temporaries BufI array[0..N-1] temporaries Output: Info error code (">0"=OK, "<0"=bad) RMS training set RMS error CVRMS leave-one-out RMS error Note: content of all arrays is changed by subroutine; it doesn't allocate temporaries. -- ALGLIB -- Copyright 11.12.2008 by Bochkanov Sergey *************************************************************************/void dsoptimalsplit2fast(real_1d_array &a, integer_1d_array &c, integer_1d_array &tiesbuf, integer_1d_array &cntbuf, real_1d_array &bufr, integer_1d_array &bufi, const ae_int_t n, const ae_int_t nc, const double alpha, ae_int_t &info, double &threshold, double &rms, double &cvrms, const xparams _xparams = alglib::xdefault);
bdsvd subpackagermatrixbdsvd function/************************************************************************* Singular value decomposition of a bidiagonal matrix (extended algorithm) COMMERCIAL EDITION OF ALGLIB: ! Commercial version of ALGLIB includes one important improvement of ! this function, which can be used from C++ and C#: ! * Hardware vendor library support (Intel MKL support on x64, other ! libraries on other platforms) ! ! Vendor libraries give approximately constant with respect to the ! number of worker threads) acceleration factor which depends on the CPU ! being used, problem size and "baseline" ALGLIB edition which is ! used for comparison. ! ! Generally, commercial ALGLIB is several times faster than open-source ! generic C edition, and many times faster than open-source C# edition. ! ! Multithreaded acceleration is NOT supported for this function. ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. The algorithm performs the singular value decomposition of a bidiagonal matrix B (upper or lower) representing it as B = Q*S*P^T, where Q and P - orthogonal matrices, S - diagonal matrix with non-negative elements on the main diagonal, in descending order. The algorithm finds singular values. In addition, the algorithm can calculate matrices Q and P (more precisely, not the matrices, but their product with given matrices U and VT - U*Q and (P^T)*VT)). Of course, matrices U and VT can be of any type, including identity. Furthermore, the algorithm can calculate Q'*C (this product is calculated more effectively than U*Q, because this calculation operates with rows instead of matrix columns). The feature of the algorithm is its ability to find all singular values including those which are arbitrarily close to 0 with relative accuracy close to machine precision. If the parameter IsFractionalAccuracyRequired is set to True, all singular values will have high relative accuracy close to machine precision. If the parameter is set to False, only the biggest singular value will have relative accuracy close to machine precision. The absolute error of other singular values is equal to the absolute error of the biggest singular value. Input parameters: D - main diagonal of matrix B. Array whose index ranges within [0..N-1]. E - superdiagonal (or subdiagonal) of matrix B. Array whose index ranges within [0..N-2]. N - size of matrix B. IsUpper - True, if the matrix is upper bidiagonal. IsFractionalAccuracyRequired - THIS PARAMETER IS IGNORED SINCE ALGLIB 3.5.0 SINGULAR VALUES ARE ALWAYS SEARCHED WITH HIGH ACCURACY. U - matrix to be multiplied by Q. Array whose indexes range within [0..NRU-1, 0..N-1]. The matrix can be bigger, in that case only the submatrix [0..NRU-1, 0..N-1] will be multiplied by Q. NRU - number of rows in matrix U. C - matrix to be multiplied by Q'. Array whose indexes range within [0..N-1, 0..NCC-1]. The matrix can be bigger, in that case only the submatrix [0..N-1, 0..NCC-1] will be multiplied by Q'. NCC - number of columns in matrix C. VT - matrix to be multiplied by P^T. Array whose indexes range within [0..N-1, 0..NCVT-1]. The matrix can be bigger, in that case only the submatrix [0..N-1, 0..NCVT-1] will be multiplied by P^T. NCVT - number of columns in matrix VT. Output parameters: D - singular values of matrix B in descending order. U - if NRU>0, contains matrix U*Q. VT - if NCVT>0, contains matrix (P^T)*VT. C - if NCC>0, contains matrix Q'*C. Result: True, if the algorithm has converged. False, if the algorithm hasn't converged (rare case). NOTE: multiplication U*Q is performed by means of transposition to internal buffer, multiplication and backward transposition. It helps to avoid costly columnwise operations and speed-up algorithm. Additional information: The type of convergence is controlled by the internal parameter TOL. If the parameter is greater than 0, the singular values will have relative accuracy TOL. If TOL<0, the singular values will have absolute accuracy ABS(TOL)*norm(B). By default, |TOL| falls within the range of 10*Epsilon and 100*Epsilon, where Epsilon is the machine precision. It is not recommended to use TOL less than 10*Epsilon since this will considerably slow down the algorithm and may not lead to error decreasing. History: * 31 March, 2007. changed MAXITR from 6 to 12. -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1999. *************************************************************************/bool rmatrixbdsvd(real_1d_array &d, const real_1d_array &e, const ae_int_t n, const bool isupper, const bool isfractionalaccuracyrequired, real_2d_array &u, const ae_int_t nru, real_2d_array &c, const ae_int_t ncc, real_2d_array &vt, const ae_int_t ncvt, const xparams _xparams = alglib::xdefault);
bessel subpackagebesseli0 function/************************************************************************* Modified Bessel function of order zero Returns modified Bessel function of order zero of the argument. The function is defined as i0(x) = j0( ix ). The range is partitioned into the two intervals [0,8] and (8, infinity). Chebyshev polynomial expansions are employed in each interval. ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0,30 30000 5.8e-16 1.4e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double besseli0(const double x, const xparams _xparams = alglib::xdefault);
besseli1 function/************************************************************************* Modified Bessel function of order one Returns modified Bessel function of order one of the argument. The function is defined as i1(x) = -i j1( ix ). The range is partitioned into the two intervals [0,8] and (8, infinity). Chebyshev polynomial expansions are employed in each interval. ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0, 30 30000 1.9e-15 2.1e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1985, 1987, 2000 by Stephen L. Moshier *************************************************************************/double besseli1(const double x, const xparams _xparams = alglib::xdefault);
besselj0 function/************************************************************************* Bessel function of order zero Returns Bessel function of order zero of the argument. The domain is divided into the intervals [0, 5] and (5, infinity). In the first interval the following rational approximation is used: 2 2 (w - r ) (w - r ) P (w) / Q (w) 1 2 3 8 2 where w = x and the two r's are zeros of the function. In the second interval, the Hankel asymptotic expansion is employed with two rational functions of degree 6/6 and 7/7. ACCURACY: Absolute error: arithmetic domain # trials peak rms IEEE 0, 30 60000 4.2e-16 1.1e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier *************************************************************************/double besselj0(const double x, const xparams _xparams = alglib::xdefault);
besselj1 function/************************************************************************* Bessel function of order one Returns Bessel function of order one of the argument. The domain is divided into the intervals [0, 8] and (8, infinity). In the first interval a 24 term Chebyshev expansion is used. In the second, the asymptotic trigonometric representation is employed using two rational functions of degree 5/5. ACCURACY: Absolute error: arithmetic domain # trials peak rms IEEE 0, 30 30000 2.6e-16 1.1e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier *************************************************************************/double besselj1(const double x, const xparams _xparams = alglib::xdefault);
besseljn function/************************************************************************* Bessel function of integer order Returns Bessel function of order n, where n is a (possibly negative) integer. The ratio of jn(x) to j0(x) is computed by backward recurrence. First the ratio jn/jn-1 is found by a continued fraction expansion. Then the recurrence relating successive orders is applied until j0 or j1 is reached. If n = 0 or 1 the routine for j0 or j1 is called directly. ACCURACY: Absolute error: arithmetic range # trials peak rms IEEE 0, 30 5000 4.4e-16 7.9e-17 Not suitable for large n or x. Use jv() (fractional order) instead. Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double besseljn(const ae_int_t n, const double x, const xparams _xparams = alglib::xdefault);
besselk0 function/************************************************************************* Modified Bessel function, second kind, order zero Returns modified Bessel function of the second kind of order zero of the argument. The range is partitioned into the two intervals [0,8] and (8, infinity). Chebyshev polynomial expansions are employed in each interval. ACCURACY: Tested at 2000 random points between 0 and 8. Peak absolute error (relative when K0 > 1) was 1.46e-14; rms, 4.26e-15. Relative error: arithmetic domain # trials peak rms IEEE 0, 30 30000 1.2e-15 1.6e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double besselk0(const double x, const xparams _xparams = alglib::xdefault);
besselk1 function/************************************************************************* Modified Bessel function, second kind, order one Computes the modified Bessel function of the second kind of order one of the argument. The range is partitioned into the two intervals [0,2] and (2, infinity). Chebyshev polynomial expansions are employed in each interval. ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0, 30 30000 1.2e-15 1.6e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double besselk1(const double x, const xparams _xparams = alglib::xdefault);
besselkn function/************************************************************************* Modified Bessel function, second kind, integer order Returns modified Bessel function of the second kind of order n of the argument. The range is partitioned into the two intervals [0,9.55] and (9.55, infinity). An ascending power series is used in the low range, and an asymptotic expansion in the high range. ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0,30 90000 1.8e-8 3.0e-10 Error is high only near the crossover point x = 9.55 between the two expansions used. Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1988, 2000 by Stephen L. Moshier *************************************************************************/double besselkn(const ae_int_t nn, const double x, const xparams _xparams = alglib::xdefault);
bessely0 function/************************************************************************* Bessel function of the second kind, order zero Returns Bessel function of the second kind, of order zero, of the argument. The domain is divided into the intervals [0, 5] and (5, infinity). In the first interval a rational approximation R(x) is employed to compute y0(x) = R(x) + 2 * log(x) * j0(x) / PI. Thus a call to j0() is required. In the second interval, the Hankel asymptotic expansion is employed with two rational functions of degree 6/6 and 7/7. ACCURACY: Absolute error, when y0(x) < 1; else relative error: arithmetic domain # trials peak rms IEEE 0, 30 30000 1.3e-15 1.6e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier *************************************************************************/double bessely0(const double x, const xparams _xparams = alglib::xdefault);
bessely1 function/************************************************************************* Bessel function of second kind of order one Returns Bessel function of the second kind of order one of the argument. The domain is divided into the intervals [0, 8] and (8, infinity). In the first interval a 25 term Chebyshev expansion is used, and a call to j1() is required. In the second, the asymptotic trigonometric representation is employed using two rational functions of degree 5/5. ACCURACY: Absolute error: arithmetic domain # trials peak rms IEEE 0, 30 30000 1.0e-15 1.3e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier *************************************************************************/double bessely1(const double x, const xparams _xparams = alglib::xdefault);
besselyn function/************************************************************************* Bessel function of second kind of integer order Returns Bessel function of order n, where n is a (possibly negative) integer. The function is evaluated by forward recurrence on n, starting with values computed by the routines y0() and y1(). If n = 0 or 1 the routine for y0 or y1 is called directly. ACCURACY: Absolute error, except relative when y > 1: arithmetic domain # trials peak rms IEEE 0, 30 30000 3.4e-15 4.3e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double besselyn(const ae_int_t n, const double x, const xparams _xparams = alglib::xdefault);
betaf subpackagebeta function/************************************************************************* Beta function - - | (a) | (b) beta( a, b ) = -----------. - | (a+b) For large arguments the logarithm of the function is evaluated using lgam(), then exponentiated. ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0,30 30000 8.1e-14 1.1e-14 Cephes Math Library Release 2.0: April, 1987 Copyright 1984, 1987 by Stephen L. Moshier *************************************************************************/double beta(const double a, const double b, const xparams _xparams = alglib::xdefault);
binomialdistr subpackagebinomialcdistribution function/************************************************************************* Complemented binomial distribution Returns the sum of the terms k+1 through n of the Binomial probability density: n -- ( n ) j n-j > ( ) p (1-p) -- ( j ) j=k+1 The terms are not summed directly; instead the incomplete beta integral is employed, according to the formula y = bdtrc( k, n, p ) = incbet( k+1, n-k, p ). The arguments must be positive, with p ranging from 0 to 1. ACCURACY: Tested at random points (a,b,p). a,b Relative error: arithmetic domain # trials peak rms For p between 0.001 and 1: IEEE 0,100 100000 6.7e-15 8.2e-16 For p between 0 and .001: IEEE 0,100 100000 1.5e-13 2.7e-15 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier *************************************************************************/double binomialcdistribution(const ae_int_t k, const ae_int_t n, const double p, const xparams _xparams = alglib::xdefault);
binomialdistribution function/************************************************************************* Binomial distribution Returns the sum of the terms 0 through k of the Binomial probability density: k -- ( n ) j n-j > ( ) p (1-p) -- ( j ) j=0 The terms are not summed directly; instead the incomplete beta integral is employed, according to the formula y = bdtr( k, n, p ) = incbet( n-k, k+1, 1-p ). The arguments must be positive, with p ranging from 0 to 1. ACCURACY: Tested at random points (a,b,p), with p between 0 and 1. a,b Relative error: arithmetic domain # trials peak rms For p between 0.001 and 1: IEEE 0,100 100000 4.3e-15 2.6e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier *************************************************************************/double binomialdistribution(const ae_int_t k, const ae_int_t n, const double p, const xparams _xparams = alglib::xdefault);
invbinomialdistribution function/************************************************************************* Inverse binomial distribution Finds the event probability p such that the sum of the terms 0 through k of the Binomial probability density is equal to the given cumulative probability y. This is accomplished using the inverse beta integral function and the relation 1 - p = incbi( n-k, k+1, y ). ACCURACY: Tested at random points (a,b,p). a,b Relative error: arithmetic domain # trials peak rms For p between 0.001 and 1: IEEE 0,100 100000 2.3e-14 6.4e-16 IEEE 0,10000 100000 6.6e-12 1.2e-13 For p between 10^-6 and 0.001: IEEE 0,100 100000 2.0e-12 1.3e-14 IEEE 0,10000 100000 1.5e-12 3.2e-14 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier *************************************************************************/double invbinomialdistribution(const ae_int_t k, const ae_int_t n, const double y, const xparams _xparams = alglib::xdefault);
chebyshev subpackagechebyshevcalculate function/************************************************************************* Calculation of the value of the Chebyshev polynomials of the first and second kinds. Parameters: r - polynomial kind, either 1 or 2. n - degree, n>=0 x - argument, -1 <= x <= 1 Result: the value of the Chebyshev polynomial at x *************************************************************************/double chebyshevcalculate(const ae_int_t r, const ae_int_t n, const double x, const xparams _xparams = alglib::xdefault);
chebyshevcoefficients function/************************************************************************* Representation of Tn as C[0] + C[1]*X + ... + C[N]*X^N Input parameters: N - polynomial degree, n>=0 Output parameters: C - coefficients *************************************************************************/void chebyshevcoefficients(const ae_int_t n, real_1d_array &c, const xparams _xparams = alglib::xdefault);
chebyshevsum function/************************************************************************* Summation of Chebyshev polynomials using Clenshaw's recurrence formula. This routine calculates c[0]*T0(x) + c[1]*T1(x) + ... + c[N]*TN(x) or c[0]*U0(x) + c[1]*U1(x) + ... + c[N]*UN(x) depending on the R. Parameters: r - polynomial kind, either 1 or 2. n - degree, n>=0 x - argument Result: the value of the Chebyshev polynomial at x *************************************************************************/double chebyshevsum(const real_1d_array &c, const ae_int_t r, const ae_int_t n, const double x, const xparams _xparams = alglib::xdefault);
fromchebyshev function/************************************************************************* Conversion of a series of Chebyshev polynomials to a power series. Represents A[0]*T0(x) + A[1]*T1(x) + ... + A[N]*Tn(x) as B[0] + B[1]*X + ... + B[N]*X^N. Input parameters: A - Chebyshev series coefficients N - degree, N>=0 Output parameters B - power series coefficients *************************************************************************/void fromchebyshev(const real_1d_array &a, const ae_int_t n, real_1d_array &b, const xparams _xparams = alglib::xdefault);
chisquaredistr subpackagechisquarecdistribution function/************************************************************************* Complemented Chi-square distribution Returns the area under the right hand tail (from x to infinity) of the Chi square probability density function with v degrees of freedom: inf. - 1 | | v/2-1 -t/2 P( x | v ) = ----------- | t e dt v/2 - | | 2 | (v/2) - x where x is the Chi-square variable. The incomplete gamma integral is used, according to the formula y = chdtr( v, x ) = igamc( v/2.0, x/2.0 ). The arguments must both be positive. ACCURACY: See incomplete gamma function Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double chisquarecdistribution(const double v, const double x, const xparams _xparams = alglib::xdefault);
chisquaredistribution function/************************************************************************* Chi-square distribution Returns the area under the left hand tail (from 0 to x) of the Chi square probability density function with v degrees of freedom. x - 1 | | v/2-1 -t/2 P( x | v ) = ----------- | t e dt v/2 - | | 2 | (v/2) - 0 where x is the Chi-square variable. The incomplete gamma integral is used, according to the formula y = chdtr( v, x ) = igam( v/2.0, x/2.0 ). The arguments must both be positive. ACCURACY: See incomplete gamma function Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double chisquaredistribution(const double v, const double x, const xparams _xparams = alglib::xdefault);
invchisquaredistribution function/************************************************************************* Inverse of complemented Chi-square distribution Finds the Chi-square argument x such that the integral from x to infinity of the Chi-square density is equal to the given cumulative probability y. This is accomplished using the inverse gamma integral function and the relation x/2 = igami( df/2, y ); ACCURACY: See inverse incomplete gamma function Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double invchisquaredistribution(const double v, const double y, const xparams _xparams = alglib::xdefault);
clustering subpackage| clst_ahc | Simple hierarchical clusterization with Euclidean distance function | |
| clst_distance | Clusterization with different metric types | |
| clst_kclusters | Obtaining K top clusters from clusterization tree | |
| clst_kmeans | Simple k-means clusterization | |
| clst_linkage | Clusterization with different linkage types |
ahcreport class/************************************************************************* This structure is used to store results of the agglomerative hierarchical clustering (AHC). Following information is returned: * TerminationType - completion code: * 1 for successful completion of algorithm * -5 inappropriate combination of clustering algorithm and distance function was used. As for now, it is possible only when Ward's method is called for dataset with non-Euclidean distance function. In case negative completion code is returned, other fields of report structure are invalid and should not be used. * NPoints contains number of points in the original dataset * Z contains information about merges performed (see below). Z contains indexes from the original (unsorted) dataset and it can be used when you need to know what points were merged. However, it is not convenient when you want to build a dendrograd (see below). * if you want to build dendrogram, you can use Z, but it is not good option, because Z contains indexes from unsorted dataset. Dendrogram built from such dataset is likely to have intersections. So, you have to reorder you points before building dendrogram. Permutation which reorders point is returned in P. Another representation of merges, which is more convenient for dendorgram construction, is returned in PM. * more information on format of Z, P and PM can be found below and in the examples from ALGLIB Reference Manual. FORMAL DESCRIPTION OF FIELDS: NPoints number of points Z array[NPoints-1,2], contains indexes of clusters linked in pairs to form clustering tree. I-th row corresponds to I-th merge: * Z[I,0] - index of the first cluster to merge * Z[I,1] - index of the second cluster to merge * Z[I,0]<Z[I,1] * clusters are numbered from 0 to 2*NPoints-2, with indexes from 0 to NPoints-1 corresponding to points of the original dataset, and indexes from NPoints to 2*NPoints-2 correspond to clusters generated by subsequent merges (I-th row of Z creates cluster with index NPoints+I). IMPORTANT: indexes in Z[] are indexes in the ORIGINAL, unsorted dataset. In addition to Z algorithm outputs permutation which rearranges points in such way that subsequent merges are performed on adjacent points (such order is needed if you want to build dendrogram). However, indexes in Z are related to original, unrearranged sequence of points. P array[NPoints], permutation which reorders points for dendrogram construction. P[i] contains index of the position where we should move I-th point of the original dataset in order to apply merges PZ/PM. PZ same as Z, but for permutation of points given by P. The only thing which changed are indexes of the original points; indexes of clusters remained same. MergeDist array[NPoints-1], contains distances between clusters being merged (MergeDist[i] correspond to merge stored in Z[i,...]): * CLINK, SLINK and average linkage algorithms report "raw", unmodified distance metric. * Ward's method reports weighted intra-cluster variance, which is equal to ||Ca-Cb||^2 * Sa*Sb/(Sa+Sb). Here A and B are clusters being merged, Ca is a center of A, Cb is a center of B, Sa is a size of A, Sb is a size of B. PM array[NPoints-1,6], another representation of merges, which is suited for dendrogram construction. It deals with rearranged points (permutation P is applied) and represents merges in a form which different from one used by Z. For each I from 0 to NPoints-2, I-th row of PM represents merge performed on two clusters C0 and C1. Here: * C0 contains points with indexes PM[I,0]...PM[I,1] * C1 contains points with indexes PM[I,2]...PM[I,3] * indexes stored in PM are given for dataset sorted according to permutation P * PM[I,1]=PM[I,2]-1 (only adjacent clusters are merged) * PM[I,0]<=PM[I,1], PM[I,2]<=PM[I,3], i.e. both clusters contain at least one point * heights of "subdendrograms" corresponding to C0/C1 are stored in PM[I,4] and PM[I,5]. Subdendrograms corresponding to single-point clusters have height=0. Dendrogram of the merge result has height H=max(H0,H1)+1. NOTE: there is one-to-one correspondence between merges described by Z and PM. I-th row of Z describes same merge of clusters as I-th row of PM, with "left" cluster from Z corresponding to the "left" one from PM. -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/class ahcreport { public: ahcreport(); ahcreport(const ahcreport &rhs); ahcreport& operator=(const ahcreport &rhs); virtual ~ahcreport(); ae_int_t terminationtype; ae_int_t npoints; integer_1d_array p; integer_2d_array z; integer_2d_array pz; integer_2d_array pm; real_1d_array mergedist; };
clusterizerstate class/************************************************************************* This structure is a clusterization engine. You should not try to access its fields directly. Use ALGLIB functions in order to work with this object. -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/class clusterizerstate { public: clusterizerstate(); clusterizerstate(const clusterizerstate &rhs); clusterizerstate& operator=(const clusterizerstate &rhs); virtual ~clusterizerstate(); };
kmeansreport class/************************************************************************* This structure is used to store results of the k-means clustering algorithm. Following information is always returned: * NPoints contains number of points in the original dataset * TerminationType contains completion code, negative on failure, positive on success * K contains number of clusters For positive TerminationType we return: * NFeatures contains number of variables in the original dataset * C, which contains centers found by algorithm * CIdx, which maps points of the original dataset to clusters FORMAL DESCRIPTION OF FIELDS: NPoints number of points, >=0 NFeatures number of variables, >=1 TerminationType completion code: * -5 if distance type is anything different from Euclidean metric * -3 for degenerate dataset: a) less than K distinct points, b) K=0 for non-empty dataset. * +1 for successful completion K number of clusters C array[K,NFeatures], rows of the array store centers CIdx array[NPoints], which contains cluster indexes IterationsCount actual number of iterations performed by clusterizer. If algorithm performed more than one random restart, total number of iterations is returned. Energy merit function, "energy", sum of squared deviations from cluster centers -- ALGLIB -- Copyright 27.11.2012 by Bochkanov Sergey *************************************************************************/class kmeansreport { public: kmeansreport(); kmeansreport(const kmeansreport &rhs); kmeansreport& operator=(const kmeansreport &rhs); virtual ~kmeansreport(); ae_int_t npoints; ae_int_t nfeatures; ae_int_t terminationtype; ae_int_t iterationscount; double energy; ae_int_t k; real_2d_array c; integer_1d_array cidx; };
clusterizercreate function/************************************************************************* This function initializes clusterizer object. Newly initialized object is empty, i.e. it does not contain dataset. You should use it as follows: 1. creation 2. dataset is added with ClusterizerSetPoints() 3. additional parameters are set 3. clusterization is performed with one of the clustering functions -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizercreate(clusterizerstate &s, const xparams _xparams = alglib::xdefault);
clusterizergetdistances function/************************************************************************* This function returns distance matrix for dataset INPUT PARAMETERS: XY - array[NPoints,NFeatures], dataset NPoints - number of points, >=0 NFeatures- number of features, >=1 DistType- distance function: * 0 Chebyshev distance (L-inf norm) * 1 city block distance (L1 norm) * 2 Euclidean distance (L2 norm, non-squared) * 10 Pearson correlation: dist(a,b) = 1-corr(a,b) * 11 Absolute Pearson correlation: dist(a,b) = 1-|corr(a,b)| * 12 Uncentered Pearson correlation (cosine of the angle): dist(a,b) = a'*b/(|a|*|b|) * 13 Absolute uncentered Pearson correlation dist(a,b) = |a'*b|/(|a|*|b|) * 20 Spearman rank correlation: dist(a,b) = 1-rankcorr(a,b) * 21 Absolute Spearman rank correlation dist(a,b) = 1-|rankcorr(a,b)| OUTPUT PARAMETERS: D - array[NPoints,NPoints], distance matrix (full matrix is returned, with lower and upper triangles) NOTE: different distance functions have different performance penalty: * Euclidean or Pearson correlation distances are the fastest ones * Spearman correlation distance function is a bit slower * city block and Chebyshev distances are order of magnitude slower The reason behing difference in performance is that correlation-based distance functions are computed using optimized linear algebra kernels, while Chebyshev and city block distance functions are computed using simple nested loops with two branches at each iteration. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizergetdistances(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nfeatures, const ae_int_t disttype, real_2d_array &d, const xparams _xparams = alglib::xdefault);
clusterizergetkclusters function/************************************************************************* This function takes as input clusterization report Rep, desired clusters count K, and builds top K clusters from hierarchical clusterization tree. It returns assignment of points to clusters (array of cluster indexes). INPUT PARAMETERS: Rep - report from ClusterizerRunAHC() performed on XY K - desired number of clusters, 1<=K<=NPoints. K can be zero only when NPoints=0. OUTPUT PARAMETERS: CIdx - array[NPoints], I-th element contains cluster index (from 0 to K-1) for I-th point of the dataset. CZ - array[K]. This array allows to convert cluster indexes returned by this function to indexes used by Rep.Z. J-th cluster returned by this function corresponds to CZ[J]-th cluster stored in Rep.Z/PZ/PM. It is guaranteed that CZ[I]<CZ[I+1]. NOTE: K clusters built by this subroutine are assumed to have no hierarchy. Although they were obtained by manipulation with top K nodes of dendrogram (i.e. hierarchical decomposition of dataset), this function does not return information about hierarchy. Each of the clusters stand on its own. NOTE: Cluster indexes returned by this function does not correspond to indexes returned in Rep.Z/PZ/PM. Either you work with hierarchical representation of the dataset (dendrogram), or you work with "flat" representation returned by this function. Each of representations has its own clusters indexing system (former uses [0, 2*NPoints-2]), while latter uses [0..K-1]), although it is possible to perform conversion from one system to another by means of CZ array, returned by this function, which allows you to convert indexes stored in CIdx to the numeration system used by Rep.Z. NOTE: this subroutine is optimized for moderate values of K. Say, for K=5 it will perform many times faster than for K=100. Its worst-case performance is O(N*K), although in average case it perform better (up to O(N*log(K))). -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizergetkclusters(const ahcreport &rep, const ae_int_t k, integer_1d_array &cidx, integer_1d_array &cz, const xparams _xparams = alglib::xdefault);
clusterizerrunahc function/************************************************************************* This function performs agglomerative hierarchical clustering NOTE: Agglomerative hierarchical clustering algorithm has two phases: distance matrix calculation and clustering itself. Only first phase (distance matrix calculation) is accelerated by SIMD and SMP. Thus, acceleration is significant only for medium or high-dimensional problems. Although activating multithreading gives some speedup over single- threaded execution, you should not expect nearly-linear scaling with respect to cores count. INPUT PARAMETERS: S - clusterizer state, initialized by ClusterizerCreate() OUTPUT PARAMETERS: Rep - clustering results; see description of AHCReport structure for more information. NOTE 1: hierarchical clustering algorithms require large amounts of memory. In particular, this implementation needs sizeof(double)*NPoints^2 bytes, which are used to store distance matrix. In case we work with user-supplied matrix, this amount is multiplied by 2 (we have to store original matrix and to work with its copy). For example, problem with 10000 points would require 800M of RAM, even when working in a 1-dimensional space. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizerrunahc(clusterizerstate &s, ahcreport &rep, const xparams _xparams = alglib::xdefault);
clusterizerrunkmeans function/************************************************************************* This function performs clustering by k-means++ algorithm. You may change algorithm properties by calling: * ClusterizerSetKMeansLimits() to change number of restarts or iterations * ClusterizerSetKMeansInit() to change initialization algorithm By default, one restart and unlimited number of iterations are used. Initialization algorithm is chosen automatically. NOTE: k-means clustering algorithm has two phases: selection of initial centers and clustering itself. ALGLIB parallelizes both phases. Parallel version is optimized for the following scenario: medium or high-dimensional problem (8 or more dimensions) with large number of points and clusters. However, some speed-up can be obtained even when assumptions above are violated. INPUT PARAMETERS: S - clusterizer state, initialized by ClusterizerCreate() K - number of clusters, K>=0. K can be zero only when algorithm is called for empty dataset, in this case completion code is set to success (+1). If K=0 and dataset size is non-zero, we can not meaningfully assign points to some center (there are no centers because K=0) and return -3 as completion code (failure). OUTPUT PARAMETERS: Rep - clustering results; see description of KMeansReport structure for more information. NOTE 1: k-means clustering can be performed only for datasets with Euclidean distance function. Algorithm will return negative completion code in Rep.TerminationType in case dataset was added to clusterizer with DistType other than Euclidean (or dataset was specified by distance matrix instead of explicitly given points). NOTE 2: by default, k-means uses non-deterministic seed to initialize RNG which is used to select initial centers. As result, each run of algorithm may return different values. If you need deterministic behavior, use ClusterizerSetSeed() function. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizerrunkmeans(clusterizerstate &s, const ae_int_t k, kmeansreport &rep, const xparams _xparams = alglib::xdefault);
clusterizerseparatedbycorr function/************************************************************************* This function accepts AHC report Rep, desired maximum intercluster correlation and returns top clusters from hierarchical clusterization tree which are separated by correlation R or LOWER. It returns assignment of points to clusters (array of cluster indexes). There is one more function with similar name - ClusterizerSeparatedByDist, which returns clusters with intercluster distance equal to R or HIGHER (note: higher for distance, lower for correlation). INPUT PARAMETERS: Rep - report from ClusterizerRunAHC() performed on XY R - desired maximum intercluster correlation, -1<=R<=+1 OUTPUT PARAMETERS: K - number of clusters, 1<=K<=NPoints CIdx - array[NPoints], I-th element contains cluster index (from 0 to K-1) for I-th point of the dataset. CZ - array[K]. This array allows to convert cluster indexes returned by this function to indexes used by Rep.Z. J-th cluster returned by this function corresponds to CZ[J]-th cluster stored in Rep.Z/PZ/PM. It is guaranteed that CZ[I]<CZ[I+1]. NOTE: K clusters built by this subroutine are assumed to have no hierarchy. Although they were obtained by manipulation with top K nodes of dendrogram (i.e. hierarchical decomposition of dataset), this function does not return information about hierarchy. Each of the clusters stand on its own. NOTE: Cluster indexes returned by this function does not correspond to indexes returned in Rep.Z/PZ/PM. Either you work with hierarchical representation of the dataset (dendrogram), or you work with "flat" representation returned by this function. Each of representations has its own clusters indexing system (former uses [0, 2*NPoints-2]), while latter uses [0..K-1]), although it is possible to perform conversion from one system to another by means of CZ array, returned by this function, which allows you to convert indexes stored in CIdx to the numeration system used by Rep.Z. NOTE: this subroutine is optimized for moderate values of K. Say, for K=5 it will perform many times faster than for K=100. Its worst-case performance is O(N*K), although in average case it perform better (up to O(N*log(K))). -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizerseparatedbycorr(const ahcreport &rep, const double r, ae_int_t &k, integer_1d_array &cidx, integer_1d_array &cz, const xparams _xparams = alglib::xdefault);
clusterizerseparatedbydist function/************************************************************************* This function accepts AHC report Rep, desired minimum intercluster distance and returns top clusters from hierarchical clusterization tree which are separated by distance R or HIGHER. It returns assignment of points to clusters (array of cluster indexes). There is one more function with similar name - ClusterizerSeparatedByCorr, which returns clusters with intercluster correlation equal to R or LOWER (note: higher for distance, lower for correlation). INPUT PARAMETERS: Rep - report from ClusterizerRunAHC() performed on XY R - desired minimum intercluster distance, R>=0 OUTPUT PARAMETERS: K - number of clusters, 1<=K<=NPoints CIdx - array[NPoints], I-th element contains cluster index (from 0 to K-1) for I-th point of the dataset. CZ - array[K]. This array allows to convert cluster indexes returned by this function to indexes used by Rep.Z. J-th cluster returned by this function corresponds to CZ[J]-th cluster stored in Rep.Z/PZ/PM. It is guaranteed that CZ[I]<CZ[I+1]. NOTE: K clusters built by this subroutine are assumed to have no hierarchy. Although they were obtained by manipulation with top K nodes of dendrogram (i.e. hierarchical decomposition of dataset), this function does not return information about hierarchy. Each of the clusters stand on its own. NOTE: Cluster indexes returned by this function does not correspond to indexes returned in Rep.Z/PZ/PM. Either you work with hierarchical representation of the dataset (dendrogram), or you work with "flat" representation returned by this function. Each of representations has its own clusters indexing system (former uses [0, 2*NPoints-2]), while latter uses [0..K-1]), although it is possible to perform conversion from one system to another by means of CZ array, returned by this function, which allows you to convert indexes stored in CIdx to the numeration system used by Rep.Z. NOTE: this subroutine is optimized for moderate values of K. Say, for K=5 it will perform many times faster than for K=100. Its worst-case performance is O(N*K), although in average case it perform better (up to O(N*log(K))). -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizerseparatedbydist(const ahcreport &rep, const double r, ae_int_t &k, integer_1d_array &cidx, integer_1d_array &cz, const xparams _xparams = alglib::xdefault);
clusterizersetahcalgo function/************************************************************************* This function sets agglomerative hierarchical clustering algorithm INPUT PARAMETERS: S - clusterizer state, initialized by ClusterizerCreate() Algo - algorithm type: * 0 complete linkage (default algorithm) * 1 single linkage * 2 unweighted average linkage * 3 weighted average linkage * 4 Ward's method NOTE: Ward's method works correctly only with Euclidean distance, that's why algorithm will return negative termination code (failure) for any other distance type. It is possible, however, to use this method with user-supplied distance matrix. It is your responsibility to pass one which was calculated with Euclidean distance function. -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizersetahcalgo(clusterizerstate &s, const ae_int_t algo, const xparams _xparams = alglib::xdefault);
clusterizersetdistances function/************************************************************************* This function adds dataset given by distance matrix to the clusterizer structure. It is important that dataset is not given explicitly - only distance matrix is given. This function overrides all previous calls of ClusterizerSetPoints() or ClusterizerSetDistances(). INPUT PARAMETERS: S - clusterizer state, initialized by ClusterizerCreate() D - array[NPoints,NPoints], distance matrix given by its upper or lower triangle (main diagonal is ignored because its entries are expected to be zero). NPoints - number of points IsUpper - whether upper or lower triangle of D is given. NOTE 1: different clustering algorithms have different limitations: * agglomerative hierarchical clustering algorithms may be used with any kind of distance metric, including one which is given by distance matrix * k-means++ clustering algorithm may be used only with Euclidean distance function and explicitly given points - it can not be used with dataset given by distance matrix Thus, if you call this function, you will be unable to use k-means clustering algorithm to process your problem. -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizersetdistances(clusterizerstate &s, const real_2d_array &d, const ae_int_t npoints, const bool isupper, const xparams _xparams = alglib::xdefault); void clusterizersetdistances(clusterizerstate &s, const real_2d_array &d, const bool isupper, const xparams _xparams = alglib::xdefault);
Examples: [1]
clusterizersetkmeansinit function/************************************************************************* This function sets k-means initialization algorithm. Several different algorithms can be chosen, including k-means++. INPUT PARAMETERS: S - clusterizer state, initialized by ClusterizerCreate() InitAlgo- initialization algorithm: * 0 automatic selection ( different versions of ALGLIB may select different algorithms) * 1 random initialization * 2 k-means++ initialization (best quality of initial centers, but long non-parallelizable initialization phase with bad cache locality) * 3 "fast-greedy" algorithm with efficient, easy to parallelize initialization. Quality of initial centers is somewhat worse than that of k-means++. This algorithm is a default one in the current version of ALGLIB. *-1 "debug" algorithm which always selects first K rows of dataset; this algorithm is used for debug purposes only. Do not use it in the industrial code! -- ALGLIB -- Copyright 21.01.2015 by Bochkanov Sergey *************************************************************************/void clusterizersetkmeansinit(clusterizerstate &s, const ae_int_t initalgo, const xparams _xparams = alglib::xdefault);
clusterizersetkmeanslimits function/************************************************************************* This function sets k-means properties: number of restarts and maximum number of iterations per one run. INPUT PARAMETERS: S - clusterizer state, initialized by ClusterizerCreate() Restarts- restarts count, >=1. k-means++ algorithm performs several restarts and chooses best set of centers (one with minimum squared distance). MaxIts - maximum number of k-means iterations performed during one run. >=0, zero value means that algorithm performs unlimited number of iterations. -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizersetkmeanslimits(clusterizerstate &s, const ae_int_t restarts, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
clusterizersetpoints function/************************************************************************* This function adds dataset to the clusterizer structure. This function overrides all previous calls of ClusterizerSetPoints() or ClusterizerSetDistances(). INPUT PARAMETERS: S - clusterizer state, initialized by ClusterizerCreate() XY - array[NPoints,NFeatures], dataset NPoints - number of points, >=0 NFeatures- number of features, >=1 DistType- distance function: * 0 Chebyshev distance (L-inf norm) * 1 city block distance (L1 norm) * 2 Euclidean distance (L2 norm), non-squared * 10 Pearson correlation: dist(a,b) = 1-corr(a,b) * 11 Absolute Pearson correlation: dist(a,b) = 1-|corr(a,b)| * 12 Uncentered Pearson correlation (cosine of the angle): dist(a,b) = a'*b/(|a|*|b|) * 13 Absolute uncentered Pearson correlation dist(a,b) = |a'*b|/(|a|*|b|) * 20 Spearman rank correlation: dist(a,b) = 1-rankcorr(a,b) * 21 Absolute Spearman rank correlation dist(a,b) = 1-|rankcorr(a,b)| NOTE 1: different distance functions have different performance penalty: * Euclidean or Pearson correlation distances are the fastest ones * Spearman correlation distance function is a bit slower * city block and Chebyshev distances are order of magnitude slower The reason behing difference in performance is that correlation-based distance functions are computed using optimized linear algebra kernels, while Chebyshev and city block distance functions are computed using simple nested loops with two branches at each iteration. NOTE 2: different clustering algorithms have different limitations: * agglomerative hierarchical clustering algorithms may be used with any kind of distance metric * k-means++ clustering algorithm may be used only with Euclidean distance function Thus, list of specific clustering algorithms you may use depends on distance function you specify when you set your dataset. -- ALGLIB -- Copyright 10.07.2012 by Bochkanov Sergey *************************************************************************/void clusterizersetpoints(clusterizerstate &s, const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nfeatures, const ae_int_t disttype, const xparams _xparams = alglib::xdefault); void clusterizersetpoints(clusterizerstate &s, const real_2d_array &xy, const ae_int_t disttype, const xparams _xparams = alglib::xdefault);
clusterizersetseed function/************************************************************************* This function sets seed which is used to initialize internal RNG. By default, deterministic seed is used - same for each run of clusterizer. If you specify non-deterministic seed value, then some algorithms which depend on random initialization (in current version: k-means) may return slightly different results after each run. INPUT PARAMETERS: S - clusterizer state, initialized by ClusterizerCreate() Seed - seed: * positive values = use deterministic seed for each run of algorithms which depend on random initialization * zero or negative values = use non-deterministic seed -- ALGLIB -- Copyright 08.06.2017 by Bochkanov Sergey *************************************************************************/void clusterizersetseed(clusterizerstate &s, const ae_int_t seed, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// The very simple clusterization example
//
// We have a set of points in 2D space:
// (P0,P1,P2,P3,P4) = ((1,1),(1,2),(4,1),(2,3),(4,1.5))
//
// |
// | P3
// |
// | P1
// | P4
// | P0 P2
// |-------------------------
//
// We want to perform Agglomerative Hierarchic Clusterization (AHC),
// using complete linkage (default algorithm) and Euclidean distance
// (default metric).
//
// In order to do that, we:
// * create clusterizer with clusterizercreate()
// * set points XY and metric (2=Euclidean) with clusterizersetpoints()
// * run AHC algorithm with clusterizerrunahc
//
// You may see that clusterization itself is a minor part of the example,
// most of which is dominated by comments :)
//
clusterizerstate s;
ahcreport rep;
real_2d_array xy = "[[1,1],[1,2],[4,1],[2,3],[4,1.5]]";
clusterizercreate(s);
clusterizersetpoints(s, xy, 2);
clusterizerrunahc(s, rep);
//
// Now we've built our clusterization tree. Rep.z contains information which
// is required to build dendrogram. I-th row of rep.z represents one merge
// operation, with first cluster to merge having index rep.z[I,0] and second
// one having index rep.z[I,1]. Merge result has index NPoints+I.
//
// Clusters with indexes less than NPoints are single-point initial clusters,
// while ones with indexes from NPoints to 2*NPoints-2 are multi-point
// clusters created during merges.
//
// In our example, Z=[[2,4], [0,1], [3,6], [5,7]]
//
// It means that:
// * first, we merge C2=(P2) and C4=(P4), and create C5=(P2,P4)
// * then, we merge C2=(P0) and C1=(P1), and create C6=(P0,P1)
// * then, we merge C3=(P3) and C6=(P0,P1), and create C7=(P0,P1,P3)
// * finally, we merge C5 and C7 and create C8=(P0,P1,P2,P3,P4)
//
// Thus, we have following dendrogram:
//
// ------8-----
// | |
// | ----7----
// | | |
// ---5--- | ---6---
// | | | | |
// P2 P4 P3 P0 P1
//
printf("%s\n", rep.z.tostring().c_str()); // EXPECTED: [[2,4],[0,1],[3,6],[5,7]]
//
// We've built dendrogram above by reordering our dataset.
//
// Without such reordering it would be impossible to build dendrogram without
// intersections. Luckily, ahcreport structure contains two additional fields
// which help to build dendrogram from your data:
// * rep.p, which contains permutation applied to dataset
// * rep.pm, which contains another representation of merges
//
// In our example we have:
// * P=[3,4,0,2,1]
// * PZ=[[0,0,1,1,0,0],[3,3,4,4,0,0],[2,2,3,4,0,1],[0,1,2,4,1,2]]
//
// Permutation array P tells us that P0 should be moved to position 3,
// P1 moved to position 4, P2 moved to position 0 and so on:
//
// (P0 P1 P2 P3 P4) => (P2 P4 P3 P0 P1)
//
// Merges array PZ tells us how to perform merges on the sorted dataset.
// One row of PZ corresponds to one merge operations, with first pair of
// elements denoting first of the clusters to merge (start index, end
// index) and next pair of elements denoting second of the clusters to
// merge. Clusters being merged are always adjacent, with first one on
// the left and second one on the right.
//
// For example, first row of PZ tells us that clusters [0,0] and [1,1] are
// merged (single-point clusters, with first one containing P2 and second
// one containing P4). Third row of PZ tells us that we merge one single-
// point cluster [2,2] with one two-point cluster [3,4].
//
// There are two more elements in each row of PZ. These are the helper
// elements, which denote HEIGHT (not size) of left and right subdendrograms.
// For example, according to PZ, first two merges are performed on clusterization
// trees of height 0, while next two merges are performed on 0-1 and 1-2
// pairs of trees correspondingly.
//
printf("%s\n", rep.p.tostring().c_str()); // EXPECTED: [3,4,0,2,1]
printf("%s\n", rep.pm.tostring().c_str()); // EXPECTED: [[0,0,1,1,0,0],[3,3,4,4,0,0],[2,2,3,4,0,1],[0,1,2,4,1,2]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// We have three points in 4D space:
// (P0,P1,P2) = ((1, 2, 1, 2), (6, 7, 6, 7), (7, 6, 7, 6))
//
// We want to try clustering them with different distance functions.
// Distance function is chosen when we add dataset to the clusterizer.
// We can choose several distance types - Euclidean, city block, Chebyshev,
// several correlation measures or user-supplied distance matrix.
//
// Here we'll try three distances: Euclidean, Pearson correlation,
// user-supplied distance matrix. Different distance functions lead
// to different choices being made by algorithm during clustering.
//
clusterizerstate s;
ahcreport rep;
ae_int_t disttype;
real_2d_array xy = "[[1, 2, 1, 2], [6, 7, 6, 7], [7, 6, 7, 6]]";
clusterizercreate(s);
// With Euclidean distance function (disttype=2) two closest points
// are P1 and P2, thus:
// * first, we merge P1 and P2 to form C3=[P1,P2]
// * second, we merge P0 and C3 to form C4=[P0,P1,P2]
disttype = 2;
clusterizersetpoints(s, xy, disttype);
clusterizerrunahc(s, rep);
printf("%s\n", rep.z.tostring().c_str()); // EXPECTED: [[1,2],[0,3]]
// With Pearson correlation distance function (disttype=10) situation
// is different - distance between P0 and P1 is zero, thus:
// * first, we merge P0 and P1 to form C3=[P0,P1]
// * second, we merge P2 and C3 to form C4=[P0,P1,P2]
disttype = 10;
clusterizersetpoints(s, xy, disttype);
clusterizerrunahc(s, rep);
printf("%s\n", rep.z.tostring().c_str()); // EXPECTED: [[0,1],[2,3]]
// Finally, we try clustering with user-supplied distance matrix:
// [ 0 3 1 ]
// P = [ 3 0 3 ], where P[i,j] = dist(Pi,Pj)
// [ 1 3 0 ]
//
// * first, we merge P0 and P2 to form C3=[P0,P2]
// * second, we merge P1 and C3 to form C4=[P0,P1,P2]
real_2d_array d = "[[0,3,1],[3,0,3],[1,3,0]]";
clusterizersetdistances(s, d, true);
clusterizerrunahc(s, rep);
printf("%s\n", rep.z.tostring().c_str()); // EXPECTED: [[0,2],[1,3]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// We have a set of points in 2D space:
// (P0,P1,P2,P3,P4) = ((1,1),(1,2),(4,1),(2,3),(4,1.5))
//
// |
// | P3
// |
// | P1
// | P4
// | P0 P2
// |-------------------------
//
// We perform Agglomerative Hierarchic Clusterization (AHC) and we want
// to get top K clusters from clusterization tree for different K.
//
clusterizerstate s;
ahcreport rep;
real_2d_array xy = "[[1,1],[1,2],[4,1],[2,3],[4,1.5]]";
integer_1d_array cidx;
integer_1d_array cz;
clusterizercreate(s);
clusterizersetpoints(s, xy, 2);
clusterizerrunahc(s, rep);
// with K=5, every points is assigned to its own cluster:
// C0=P0, C1=P1 and so on...
clusterizergetkclusters(rep, 5, cidx, cz);
printf("%s\n", cidx.tostring().c_str()); // EXPECTED: [0,1,2,3,4]
// with K=1 we have one large cluster C0=[P0,P1,P2,P3,P4,P5]
clusterizergetkclusters(rep, 1, cidx, cz);
printf("%s\n", cidx.tostring().c_str()); // EXPECTED: [0,0,0,0,0]
// with K=3 we have three clusters C0=[P3], C1=[P2,P4], C2=[P0,P1]
clusterizergetkclusters(rep, 3, cidx, cz);
printf("%s\n", cidx.tostring().c_str()); // EXPECTED: [2,2,1,0,1]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// The very simple clusterization example
//
// We have a set of points in 2D space:
// (P0,P1,P2,P3,P4) = ((1,1),(1,2),(4,1),(2,3),(4,1.5))
//
// |
// | P3
// |
// | P1
// | P4
// | P0 P2
// |-------------------------
//
// We want to perform k-means++ clustering with K=2.
//
// In order to do that, we:
// * create clusterizer with clusterizercreate()
// * set points XY and metric (must be Euclidean, distype=2) with clusterizersetpoints()
// * (optional) set number of restarts from random positions to 5
// * run k-means algorithm with clusterizerrunkmeans()
//
// You may see that clusterization itself is a minor part of the example,
// most of which is dominated by comments :)
//
clusterizerstate s;
kmeansreport rep;
real_2d_array xy = "[[1,1],[1,2],[4,1],[2,3],[4,1.5]]";
clusterizercreate(s);
clusterizersetpoints(s, xy, 2);
clusterizersetkmeanslimits(s, 5, 0);
clusterizerrunkmeans(s, 2, rep);
//
// We've performed clusterization, and it succeeded (completion code is +1).
//
// Now first center is stored in the first row of rep.c, second one is stored
// in the second row. rep.cidx can be used to determine which center is
// closest to some specific point of the dataset.
//
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
// We called clusterizersetpoints() with disttype=2 because k-means++
// algorithm does NOT support metrics other than Euclidean. But what if we
// try to use some other metric?
//
// We change metric type by calling clusterizersetpoints() one more time,
// and try to run k-means algo again. It fails.
//
clusterizersetpoints(s, xy, 0);
clusterizerrunkmeans(s, 2, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: -5
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// We have a set of points in 1D space:
// (P0,P1,P2,P3,P4) = (1, 3, 10, 16, 20)
//
// We want to perform Agglomerative Hierarchic Clusterization (AHC),
// using either complete or single linkage and Euclidean distance
// (default metric).
//
// First two steps merge P0/P1 and P3/P4 independently of the linkage type.
// However, third step depends on linkage type being used:
// * in case of complete linkage P2=10 is merged with [P0,P1]
// * in case of single linkage P2=10 is merged with [P3,P4]
//
clusterizerstate s;
ahcreport rep;
real_2d_array xy = "[[1],[3],[10],[16],[20]]";
integer_1d_array cidx;
integer_1d_array cz;
clusterizercreate(s);
clusterizersetpoints(s, xy, 2);
// use complete linkage, reduce set down to 2 clusters.
// print clusterization with clusterizergetkclusters(2).
// P2 must belong to [P0,P1]
clusterizersetahcalgo(s, 0);
clusterizerrunahc(s, rep);
clusterizergetkclusters(rep, 2, cidx, cz);
printf("%s\n", cidx.tostring().c_str()); // EXPECTED: [1,1,1,0,0]
// use single linkage, reduce set down to 2 clusters.
// print clusterization with clusterizergetkclusters(2).
// P2 must belong to [P2,P3]
clusterizersetahcalgo(s, 1);
clusterizerrunahc(s, rep);
clusterizergetkclusters(rep, 2, cidx, cz);
printf("%s\n", cidx.tostring().c_str()); // EXPECTED: [0,0,1,1,1]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
conv subpackageconvc1d function/************************************************************************* 1-dimensional complex convolution. For given A/B returns conv(A,B) (non-circular). Subroutine can automatically choose between three implementations: straightforward O(M*N) formula for very small N (or M), overlap-add algorithm for cases where max(M,N) is significantly larger than min(M,N), but O(M*N) algorithm is too slow, and general FFT-based formula for cases where two previous algorithms are too slow. Algorithm has max(M,N)*log(max(M,N)) complexity for any M/N. INPUT PARAMETERS A - array[M] - complex function to be transformed M - problem size B - array[N] - complex function to be transformed N - problem size OUTPUT PARAMETERS R - convolution: A*B. array[N+M-1] NOTE: It is assumed that A is zero at T<0, B is zero too. If one or both functions have non-zero values at negative T's, you can still use this subroutine - just shift its result correspondingly. NOTE: there is a buffered version of this function, ConvC1DBuf(), which can reuse space previously allocated in its output parameter R. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void convc1d(const complex_1d_array &a, const ae_int_t m, const complex_1d_array &b, const ae_int_t n, complex_1d_array &r, const xparams _xparams = alglib::xdefault);
convc1dbuf function/************************************************************************* 1-dimensional complex convolution, buffered version of ConvC1DBuf(), which does not reallocate R[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 30.11.2023 by Bochkanov Sergey *************************************************************************/void convc1dbuf(const complex_1d_array &a, const ae_int_t m, const complex_1d_array &b, const ae_int_t n, complex_1d_array &r, const xparams _xparams = alglib::xdefault);
convc1dcircular function/************************************************************************* 1-dimensional circular complex convolution. For given S/R returns conv(S,R) (circular). Algorithm has linearithmic complexity for any M/N. IMPORTANT: normal convolution is commutative, i.e. it is symmetric - conv(A,B)=conv(B,A). Cyclic convolution IS NOT. One function - S - is a signal, periodic function, and another - R - is a response, non-periodic function with limited length. INPUT PARAMETERS S - array[M] - complex periodic signal M - problem size B - array[N] - complex non-periodic response N - problem size OUTPUT PARAMETERS R - convolution: A*B. array[M]. NOTE: It is assumed that B is zero at T<0. If it has non-zero values at negative T's, you can still use this subroutine - just shift its result correspondingly. NOTE: there is a buffered version of this function, ConvC1DCircularBuf(), which can reuse space previously allocated in its output parameter R. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void convc1dcircular(const complex_1d_array &s, const ae_int_t m, const complex_1d_array &r, const ae_int_t n, complex_1d_array &c, const xparams _xparams = alglib::xdefault);
convc1dcircularbuf function/************************************************************************* 1-dimensional circular complex convolution. Buffered version of ConvC1DCircular(), which does not reallocate C[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 30.11.2023 by Bochkanov Sergey *************************************************************************/void convc1dcircularbuf(const complex_1d_array &s, const ae_int_t m, const complex_1d_array &r, const ae_int_t n, complex_1d_array &c, const xparams _xparams = alglib::xdefault);
convc1dcircularinv function/************************************************************************* 1-dimensional circular complex deconvolution (inverse of ConvC1DCircular()). Algorithm has M*log(M)) complexity for any M (composite or prime). INPUT PARAMETERS A - array[0..M-1] - convolved periodic signal, A = conv(R, B) M - convolved signal length B - array[0..N-1] - non-periodic response N - response length OUTPUT PARAMETERS R - deconvolved signal. array[0..M-1]. NOTE: deconvolution is unstable process and may result in division by zero (if your response function is degenerate, i.e. has zero Fourier coefficient). NOTE: It is assumed that B is zero at T<0. If it has non-zero values at negative T's, you can still use this subroutine - just shift its result correspondingly. NOTE: there is a buffered version of this function, ConvC1DCircularInvBuf(), which can reuse space previously allocated in its output parameter R. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void convc1dcircularinv(const complex_1d_array &a, const ae_int_t m, const complex_1d_array &b, const ae_int_t n, complex_1d_array &r, const xparams _xparams = alglib::xdefault);
convc1dcircularinvbuf function/************************************************************************* 1-dimensional circular complex deconvolution (inverse of ConvC1DCircular()). Buffered version of ConvC1DCircularInv(), which does not reallocate R[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 30.11.2023 by Bochkanov Sergey *************************************************************************/void convc1dcircularinvbuf(const complex_1d_array &a, const ae_int_t m, const complex_1d_array &b, const ae_int_t n, complex_1d_array &r, const xparams _xparams = alglib::xdefault);
convc1dinv function/************************************************************************* 1-dimensional complex non-circular deconvolution (inverse of ConvC1D()). Algorithm has M*log(M)) complexity for any M (composite or prime). INPUT PARAMETERS A - array[0..M-1] - convolved signal, A = conv(R, B) M - convolved signal length B - array[0..N-1] - response N - response length, N<=M OUTPUT PARAMETERS R - deconvolved signal. array[0..M-N]. NOTE: deconvolution is unstable process and may result in division by zero (if your response function is degenerate, i.e. has zero Fourier coefficient). NOTE: It is assumed that A is zero at T<0, B is zero too. If one or both functions have non-zero values at negative T's, you can still use this subroutine - just shift its result correspondingly. NOTE: there is a buffered version of this function, ConvC1DInvBuf(), which can reuse space previously allocated in its output parameter R -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void convc1dinv(const complex_1d_array &a, const ae_int_t m, const complex_1d_array &b, const ae_int_t n, complex_1d_array &r, const xparams _xparams = alglib::xdefault);
convc1dinvbuf function/************************************************************************* 1-dimensional complex non-circular deconvolution (inverse of ConvC1D()). A buffered version, which does not reallocate R[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 30.11.2023 by Bochkanov Sergey *************************************************************************/void convc1dinvbuf(const complex_1d_array &a, const ae_int_t m, const complex_1d_array &b, const ae_int_t n, complex_1d_array &r, const xparams _xparams = alglib::xdefault);
convr1d function/************************************************************************* 1-dimensional real convolution. Analogous to ConvC1D(), see ConvC1D() comments for more details. INPUT PARAMETERS A - array[0..M-1] - real function to be transformed M - problem size B - array[0..N-1] - real function to be transformed N - problem size OUTPUT PARAMETERS R - convolution: A*B. array[0..N+M-2]. NOTE: It is assumed that A is zero at T<0, B is zero too. If one or both functions have non-zero values at negative T's, you can still use this subroutine - just shift its result correspondingly. NOTE: there is a buffered version of this function, ConvR1DBuf(), which can reuse space previously allocated in its output parameter R. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void convr1d(const real_1d_array &a, const ae_int_t m, const real_1d_array &b, const ae_int_t n, real_1d_array &r, const xparams _xparams = alglib::xdefault);
convr1dbuf function/************************************************************************* 1-dimensional real convolution. Buffered version of ConvR1D(), which does not reallocate R[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 30.11.2023 by Bochkanov Sergey *************************************************************************/void convr1dbuf(const real_1d_array &a, const ae_int_t m, const real_1d_array &b, const ae_int_t n, real_1d_array &r, const xparams _xparams = alglib::xdefault);
convr1dcircular function/************************************************************************* 1-dimensional circular real convolution. Analogous to ConvC1DCircular(), see ConvC1DCircular() comments for more details. INPUT PARAMETERS S - array[0..M-1] - real signal M - problem size B - array[0..N-1] - real response N - problem size OUTPUT PARAMETERS R - convolution: A*B. array[0..M-1]. NOTE: It is assumed that B is zero at T<0. If it has non-zero values at negative T's, you can still use this subroutine - just shift its result correspondingly. NOTE: there is a buffered version of this function, ConvR1DCurcularBuf(), which can reuse space previously allocated in its output parameter R. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void convr1dcircular(const real_1d_array &s, const ae_int_t m, const real_1d_array &r, const ae_int_t n, real_1d_array &c, const xparams _xparams = alglib::xdefault);
convr1dcircularbuf function/************************************************************************* 1-dimensional circular real convolution, buffered version, which does not reallocate C[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 30.11.2023 by Bochkanov Sergey *************************************************************************/void convr1dcircularbuf(const real_1d_array &s, const ae_int_t m, const real_1d_array &r, const ae_int_t n, real_1d_array &c, const xparams _xparams = alglib::xdefault);
convr1dcircularinv function/************************************************************************* 1-dimensional complex deconvolution (inverse of ConvC1D()). Algorithm has M*log(M)) complexity for any M (composite or prime). INPUT PARAMETERS A - array[0..M-1] - convolved signal, A = conv(R, B) M - convolved signal length B - array[0..N-1] - response N - response length OUTPUT PARAMETERS R - deconvolved signal. array[0..M-N]. NOTE: deconvolution is unstable process and may result in division by zero (if your response function is degenerate, i.e. has zero Fourier coefficient). NOTE: It is assumed that B is zero at T<0. If it has non-zero values at negative T's, you can still use this subroutine - just shift its result correspondingly. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void convr1dcircularinv(const real_1d_array &a, const ae_int_t m, const real_1d_array &b, const ae_int_t n, real_1d_array &r, const xparams _xparams = alglib::xdefault);
convr1dcircularinvbuf function/************************************************************************* 1-dimensional complex deconvolution, inverse of ConvR1DCircular(). Buffered version, which does not reallocate R[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void convr1dcircularinvbuf(const real_1d_array &a, const ae_int_t m, const real_1d_array &b, const ae_int_t n, real_1d_array &r, const xparams _xparams = alglib::xdefault);
convr1dinv function/************************************************************************* 1-dimensional real deconvolution (inverse of ConvC1D()). Algorithm has M*log(M)) complexity for any M (composite or prime). INPUT PARAMETERS A - array[0..M-1] - convolved signal, A = conv(R, B) M - convolved signal length B - array[0..N-1] - response N - response length, N<=M OUTPUT PARAMETERS R - deconvolved signal. array[0..M-N]. NOTE: deconvolution is unstable process and may result in division by zero (if your response function is degenerate, i.e. has zero Fourier coefficient). NOTE: It is assumed that A is zero at T<0, B is zero too. If one or both functions have non-zero values at negative T's, you can still use this subroutine - just shift its result correspondingly. NOTE: there is a buffered version of this function, ConvR1DInvBuf(), which can reuse space previously allocated in its output parameter R. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void convr1dinv(const real_1d_array &a, const ae_int_t m, const real_1d_array &b, const ae_int_t n, real_1d_array &r, const xparams _xparams = alglib::xdefault);
convr1dinvbuf function/************************************************************************* 1-dimensional real deconvolution (inverse of ConvR1D()), buffered version, which does not reallocate R[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 30.11.2023 by Bochkanov Sergey *************************************************************************/void convr1dinvbuf(const real_1d_array &a, const ae_int_t m, const real_1d_array &b, const ae_int_t n, real_1d_array &r, const xparams _xparams = alglib::xdefault);
corr subpackagecorrc1d function/************************************************************************* 1-dimensional complex cross-correlation. For given Pattern/Signal returns corr(Pattern,Signal) (non-circular). Correlation is calculated using reduction to convolution. Algorithm with max(N,N)*log(max(N,N)) complexity is used (see ConvC1D() for more info about performance). IMPORTANT: for historical reasons subroutine accepts its parameters in reversed order: CorrC1D(Signal, Pattern) = Pattern x Signal (using traditional definition of cross-correlation, denoting cross-correlation as "x"). INPUT PARAMETERS Signal - array[0..N-1] - complex function to be transformed, signal containing pattern N - problem size Pattern - array[0..M-1] - complex function to be transformed, pattern to 'search' within a signal M - problem size OUTPUT PARAMETERS R - cross-correlation, array[0..N+M-2]: * positive lags are stored in R[0..N-1], R[i] = sum(conj(pattern[j])*signal[i+j] * negative lags are stored in R[N..N+M-2], R[N+M-1-i] = sum(conj(pattern[j])*signal[-i+j] NOTE: It is assumed that pattern domain is [0..M-1]. If Pattern is non-zero on [-K..M-1], you can still use this subroutine, just shift result by K. NOTE: there is a buffered version of this function, CorrC1DBuf(), which can reuse space previously allocated in its output parameter R. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void corrc1d(const complex_1d_array &signal, const ae_int_t n, const complex_1d_array &pattern, const ae_int_t m, complex_1d_array &r, const xparams _xparams = alglib::xdefault);
corrc1dbuf function/************************************************************************* 1-dimensional complex cross-correlation, a buffered version of CorrC1D() which does not reallocate R[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void corrc1dbuf(const complex_1d_array &signal, const ae_int_t n, const complex_1d_array &pattern, const ae_int_t m, complex_1d_array &r, const xparams _xparams = alglib::xdefault);
corrc1dcircular function/************************************************************************* 1-dimensional circular complex cross-correlation. For given Pattern/Signal returns corr(Pattern,Signal) (circular). Algorithm has linearithmic complexity for any M/N. IMPORTANT: for historical reasons subroutine accepts its parameters in reversed order: CorrC1DCircular(Signal, Pattern) = Pattern x Signal (using traditional definition of cross-correlation, denoting cross-correlation as "x"). INPUT PARAMETERS Signal - array[0..N-1] - complex function to be transformed, periodic signal containing pattern N - problem size Pattern - array[0..M-1] - complex function to be transformed, non-periodic pattern to 'search' within a signal M - problem size OUTPUT PARAMETERS R - convolution: A*B. array[0..M-1]. NOTE: there is a buffered version of this function, CorrC1DCircular(), which can reuse space previously allocated in its output parameter R. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void corrc1dcircular(const complex_1d_array &signal, const ae_int_t m, const complex_1d_array &pattern, const ae_int_t n, complex_1d_array &c, const xparams _xparams = alglib::xdefault);
corrc1dcircularbuf function/************************************************************************* 1-dimensional circular complex cross-correlation. A buffered function which does not reallocate C[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void corrc1dcircularbuf(const complex_1d_array &signal, const ae_int_t m, const complex_1d_array &pattern, const ae_int_t n, complex_1d_array &c, const xparams _xparams = alglib::xdefault);
corrr1d function/************************************************************************* 1-dimensional real cross-correlation. For given Pattern/Signal returns corr(Pattern,Signal) (non-circular). Correlation is calculated using reduction to convolution. Algorithm with max(N,N)*log(max(N,N)) complexity is used (see ConvC1D() for more info about performance). IMPORTANT: for historical reasons subroutine accepts its parameters in reversed order: CorrR1D(Signal, Pattern) = Pattern x Signal (using traditional definition of cross-correlation, denoting cross-correlation as "x"). INPUT PARAMETERS Signal - array[0..N-1] - real function to be transformed, signal containing pattern N - problem size Pattern - array[0..M-1] - real function to be transformed, pattern to 'search' withing signal M - problem size OUTPUT PARAMETERS R - cross-correlation, array[0..N+M-2]: * positive lags are stored in R[0..N-1], R[i] = sum(pattern[j]*signal[i+j] * negative lags are stored in R[N..N+M-2], R[N+M-1-i] = sum(pattern[j]*signal[-i+j] NOTE: It is assumed that pattern domain is [0..M-1]. If Pattern is non-zero on [-K..M-1], you can still use this subroutine, just shift result by K. NOTE: there is a buffered version of this function, CorrR1DBuf(), which can reuse space previously allocated in its output parameter R. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void corrr1d(const real_1d_array &signal, const ae_int_t n, const real_1d_array &pattern, const ae_int_t m, real_1d_array &r, const xparams _xparams = alglib::xdefault);
corrr1dbuf function/************************************************************************* 1-dimensional real cross-correlation, buffered function, which does not reallocate R[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void corrr1dbuf(const real_1d_array &signal, const ae_int_t n, const real_1d_array &pattern, const ae_int_t m, real_1d_array &r, const xparams _xparams = alglib::xdefault);
corrr1dcircular function/************************************************************************* 1-dimensional circular real cross-correlation. For given Pattern/Signal returns corr(Pattern,Signal) (circular). Algorithm has linearithmic complexity for any M/N. IMPORTANT: for historical reasons subroutine accepts its parameters in reversed order: CorrR1DCircular(Signal, Pattern) = Pattern x Signal (using traditional definition of cross-correlation, denoting cross-correlation as "x"). INPUT PARAMETERS Signal - array[0..N-1] - real function to be transformed, periodic signal containing pattern N - problem size Pattern - array[0..M-1] - real function to be transformed, non-periodic pattern to search withing signal M - problem size OUTPUT PARAMETERS R - convolution: A*B. array[0..M-1]. NOTE: there is a buffered version of this function, CorrR1DCircularBuf(), which can reuse space previously allocated in its output parameter C. -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void corrr1dcircular(const real_1d_array &signal, const ae_int_t m, const real_1d_array &pattern, const ae_int_t n, real_1d_array &c, const xparams _xparams = alglib::xdefault);
corrr1dcircularbuf function/************************************************************************* 1-dimensional circular real cross-correlation, buffered version , which does not reallocate C[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 21.07.2009 by Bochkanov Sergey *************************************************************************/void corrr1dcircularbuf(const real_1d_array &signal, const ae_int_t m, const real_1d_array &pattern, const ae_int_t n, real_1d_array &c, const xparams _xparams = alglib::xdefault);
correlationtests subpackagepearsoncorrelationsignificance function/************************************************************************* Pearson's correlation coefficient significance test This test checks hypotheses about whether X and Y are samples of two continuous distributions having zero correlation or whether their correlation is non-zero. The following tests are performed: * two-tailed test (null hypothesis - X and Y have zero correlation) * left-tailed test (null hypothesis - the correlation coefficient is greater than or equal to 0) * right-tailed test (null hypothesis - the correlation coefficient is less than or equal to 0). Requirements: * the number of elements in each sample is not less than 5 * normality of distributions of X and Y. Input parameters: R - Pearson's correlation coefficient for X and Y N - number of elements in samples, N>=5. Output parameters: BothTails - p-value for two-tailed test. If BothTails is less than the given significance level the null hypothesis is rejected. LeftTail - p-value for left-tailed test. If LeftTail is less than the given significance level, the null hypothesis is rejected. RightTail - p-value for right-tailed test. If RightTail is less than the given significance level the null hypothesis is rejected. -- ALGLIB -- Copyright 09.04.2007 by Bochkanov Sergey *************************************************************************/void pearsoncorrelationsignificance(const double r, const ae_int_t n, double &bothtails, double &lefttail, double &righttail, const xparams _xparams = alglib::xdefault);
spearmanrankcorrelationsignificance function/************************************************************************* Spearman's rank correlation coefficient significance test This test checks hypotheses about whether X and Y are samples of two continuous distributions having zero correlation or whether their correlation is non-zero. The following tests are performed: * two-tailed test (null hypothesis - X and Y have zero correlation) * left-tailed test (null hypothesis - the correlation coefficient is greater than or equal to 0) * right-tailed test (null hypothesis - the correlation coefficient is less than or equal to 0). Requirements: * the number of elements in each sample is not less than 5. The test is non-parametric and doesn't require distributions X and Y to be normal. Input parameters: R - Spearman's rank correlation coefficient for X and Y N - number of elements in samples, N>=5. Output parameters: BothTails - p-value for two-tailed test. If BothTails is less than the given significance level the null hypothesis is rejected. LeftTail - p-value for left-tailed test. If LeftTail is less than the given significance level, the null hypothesis is rejected. RightTail - p-value for right-tailed test. If RightTail is less than the given significance level the null hypothesis is rejected. -- ALGLIB -- Copyright 09.04.2007 by Bochkanov Sergey *************************************************************************/void spearmanrankcorrelationsignificance(const double r, const ae_int_t n, double &bothtails, double &lefttail, double &righttail, const xparams _xparams = alglib::xdefault);
datacomp subpackagekmeansgenerate function/************************************************************************* k-means++ clusterization. Backward compatibility function, we recommend to use CLUSTERING subpackage as better replacement. -- ALGLIB -- Copyright 21.03.2009 by Bochkanov Sergey *************************************************************************/void kmeansgenerate(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t k, const ae_int_t restarts, ae_int_t &info, real_2d_array &c, integer_1d_array &xyc, const xparams _xparams = alglib::xdefault);
dawson subpackagedawsonintegral function/************************************************************************* Dawson's Integral Approximates the integral x - 2 | | 2 dawsn(x) = exp( -x ) | exp( t ) dt | | - 0 Three different rational approximations are employed, for the intervals 0 to 3.25; 3.25 to 6.25; and 6.25 up. ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0,10 10000 6.9e-16 1.0e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier *************************************************************************/double dawsonintegral(const double x, const xparams _xparams = alglib::xdefault);
dforest subpackage| randomforest_cls | Simple classification with random forests | |
| randomforest_reg | Simple regression with decision forest |
decisionforest class/************************************************************************* Decision forest (random forest) model. *************************************************************************/class decisionforest { public: decisionforest(); decisionforest(const decisionforest &rhs); decisionforest& operator=(const decisionforest &rhs); virtual ~decisionforest(); };
decisionforestbuffer class/************************************************************************* Buffer object which is used to perform various requests (usually model inference) in the multithreaded mode (multiple threads working with same DF object). This object should be created with DFCreateBuffer(). *************************************************************************/class decisionforestbuffer { public: decisionforestbuffer(); decisionforestbuffer(const decisionforestbuffer &rhs); decisionforestbuffer& operator=(const decisionforestbuffer &rhs); virtual ~decisionforestbuffer(); };
decisionforestbuilder class/************************************************************************* A random forest (decision forest) builder object. Used to store dataset and specify decision forest training algorithm settings. *************************************************************************/class decisionforestbuilder { public: decisionforestbuilder(); decisionforestbuilder(const decisionforestbuilder &rhs); decisionforestbuilder& operator=(const decisionforestbuilder &rhs); virtual ~decisionforestbuilder(); };
dfreport class/************************************************************************* Decision forest training report. === training/oob errors ================================================== Following fields store training set errors: * relclserror - fraction of misclassified cases, [0,1] * avgce - average cross-entropy in bits per symbol * rmserror - root-mean-square error * avgerror - average error * avgrelerror - average relative error Out-of-bag estimates are stored in fields with same names, but "oob" prefix. For classification problems: * RMS, AVG and AVGREL errors are calculated for posterior probabilities For regression problems: * RELCLS and AVGCE errors are zero === variable importance ================================================== Following fields are used to store variable importance information: * topvars - variables ordered from the most important to less important ones (according to current choice of importance raiting). For example, topvars[0] contains index of the most important variable, and topvars[0:2] are indexes of 3 most important ones and so on. * varimportances - array[nvars], ratings (the larger, the more important the variable is, always in [0,1] range). By default, filled by zeros (no importance ratings are provided unless you explicitly request them). Zero rating means that variable is not important, however you will rarely encounter such a thing, in many cases unimportant variables produce nearly-zero (but nonzero) ratings. Variable importance report must be EXPLICITLY requested by calling: * dfbuildersetimportancegini() function, if you need out-of-bag Gini-based importance rating also known as MDI (fast to calculate, resistant to overfitting issues, but has some bias towards continuous and high-cardinality categorical variables) * dfbuildersetimportancetrngini() function, if you need training set Gini- -based importance rating (what other packages typically report). * dfbuildersetimportancepermutation() function, if you need permutation- based importance rating also known as MDA (slower to calculate, but less biased) * dfbuildersetimportancenone() function, if you do not need importance ratings - ratings will be zero, topvars[] will be [0,1,2,...] Different importance ratings (Gini or permutation) produce non-comparable values. Although in all cases rating values lie in [0,1] range, there are exist differences: * informally speaking, Gini importance rating tends to divide "unit amount of importance" between several important variables, i.e. it produces estimates which roughly sum to 1.0 (or less than 1.0, if your task can not be solved exactly). If all variables are equally important, they will have same rating, roughly 1/NVars, even if every variable is critically important. * from the other side, permutation importance tells us what percentage of the model predictive power will be ruined by permuting this specific variable. It does not produce estimates which sum to one. Critically important variable will have rating close to 1.0, and you may have multiple variables with such a rating. More information on variable importance ratings can be found in comments on the dfbuildersetimportancegini() and dfbuildersetimportancepermutation() functions. *************************************************************************/class dfreport { public: dfreport(); dfreport(const dfreport &rhs); dfreport& operator=(const dfreport &rhs); virtual ~dfreport(); double relclserror; double avgce; double rmserror; double avgerror; double avgrelerror; double oobrelclserror; double oobavgce; double oobrmserror; double oobavgerror; double oobavgrelerror; integer_1d_array topvars; real_1d_array varimportances; };
dfavgce function/************************************************************************* Average cross-entropy (in bits per element) on the test set INPUT PARAMETERS: DF - decision forest model XY - test set NPoints - test set size RESULT: CrossEntropy/(NPoints*LN(2)). Zero if model solves regression task. -- ALGLIB -- Copyright 16.02.2009 by Bochkanov Sergey *************************************************************************/double dfavgce(const decisionforest &df, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
dfavgerror function/************************************************************************* Average error on the test set INPUT PARAMETERS: DF - decision forest model XY - test set NPoints - test set size RESULT: Its meaning for regression task is obvious. As for classification task, it means average error when estimating posterior probabilities. -- ALGLIB -- Copyright 16.02.2009 by Bochkanov Sergey *************************************************************************/double dfavgerror(const decisionforest &df, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
dfavgrelerror function/************************************************************************* Average relative error on the test set INPUT PARAMETERS: DF - decision forest model XY - test set NPoints - test set size RESULT: Its meaning for regression task is obvious. As for classification task, it means average relative error when estimating posterior probability of belonging to the correct class. -- ALGLIB -- Copyright 16.02.2009 by Bochkanov Sergey *************************************************************************/double dfavgrelerror(const decisionforest &df, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
dfbinarycompression function/************************************************************************* This function performs binary compression of the decision forest. Original decision forest produced by the forest builder is stored using 64-bit representation for all numbers - offsets, variable indexes, split points. It is possible to significantly reduce model size by means of: * using compressed dynamic encoding for integers (offsets and variable indexes), which uses just 1 byte to store small ints (less than 128), just 2 bytes for larger values (less than 128^2) and so on * storing floating point numbers using 8-bit exponent and 16-bit mantissa As result, model needs significantly less memory (compression factor depends on variable and class counts). In particular: * NVars<128 and NClasses<128 result in 4.4x-5.7x model size reduction * NVars<16384 and NClasses<128 result in 3.7x-4.5x model size reduction Such storage format performs lossless compression of all integers, but compression of floating point values (split values) is lossy, with roughly 0.01% relative error introduced during rounding. Thus, we recommend you to re-evaluate model accuracy after compression. Another downside of compression is ~1.5x reduction in the inference speed due to necessity of dynamic decompression of the compressed model. INPUT PARAMETERS: DF - decision forest built by forest builder OUTPUT PARAMETERS: DF - replaced by compressed forest RESULT: compression factor (in-RAM size of the compressed model vs than of the uncompressed one), positive number larger than 1.0 -- ALGLIB -- Copyright 22.07.2019 by Bochkanov Sergey *************************************************************************/double dfbinarycompression(decisionforest &df, const xparams _xparams = alglib::xdefault);
dfbuilderbuildrandomforest function/************************************************************************* This subroutine builds decision forest according to current settings using dataset internally stored in the builder object. Dense algorithm is used. NOTE: this function uses dense algorithm for forest construction independently from the dataset format (dense or sparse). NOTE: forest built with this function is stored in-memory using 64-bit data structures for offsets/indexes/split values. It is possible to convert forest into more memory-efficient compressed binary representation. Depending on the problem properties, 3.7x-5.7x compression factors are possible. The downsides of compression are (a) slight reduction in the model accuracy and (b) ~1.5x reduction in the inference speed (due to increased complexity of the storage format). See comments on dfbinarycompression() for more info. Default settings are used by the algorithm; you can tweak them with the help of the following functions: * dfbuildersetrfactor() - to control a fraction of the dataset used for subsampling * dfbuildersetrandomvars() - to control number of variables randomly chosen for decision rule creation ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: S - decision forest builder object NTrees - NTrees>=1, number of trees to train OUTPUT PARAMETERS: DF - decision forest. You can compress this forest to more compact 16-bit representation with dfbinarycompression() Rep - report, see below for information on its fields. === report information produced by forest construction function ========== Decision forest training report includes following information: * training set errors * out-of-bag estimates of errors * variable importance ratings Following fields are used to store information: * training set errors are stored in rep.relclserror, rep.avgce, rep.rmserror, rep.avgerror and rep.avgrelerror * out-of-bag estimates of errors are stored in rep.oobrelclserror, rep.oobavgce, rep.oobrmserror, rep.oobavgerror and rep.oobavgrelerror Variable importance reports, if requested by dfbuildersetimportancegini(), dfbuildersetimportancetrngini() or dfbuildersetimportancepermutation() call, are stored in: * rep.varimportances field stores importance ratings * rep.topvars stores variable indexes ordered from the most important to less important ones You can find more information about report fields in: * comments on dfreport structure * comments on dfbuildersetimportancegini function * comments on dfbuildersetimportancetrngini function * comments on dfbuildersetimportancepermutation function -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/void dfbuilderbuildrandomforest(decisionforestbuilder &s, const ae_int_t ntrees, decisionforest &df, dfreport &rep, const xparams _xparams = alglib::xdefault);
dfbuildercreate function/************************************************************************* This subroutine creates DecisionForestBuilder object which is used to train decision forests. By default, new builder stores empty dataset and some reasonable default settings. At the very least, you should specify dataset prior to building decision forest. You can also tweak settings of the forest construction algorithm (recommended, although default setting should work well). Following actions are mandatory: * calling dfbuildersetdataset() to specify dataset * calling dfbuilderbuildrandomforest() to build decision forest using current dataset and default settings Additionally, you may call: * dfbuildersetrndvars() or dfbuildersetrndvarsratio() to specify number of variables randomly chosen for each split * dfbuildersetsubsampleratio() to specify fraction of the dataset randomly subsampled to build each tree * dfbuildersetseed() to control random seed chosen for tree construction INPUT PARAMETERS: none OUTPUT PARAMETERS: S - decision forest builder -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/void dfbuildercreate(decisionforestbuilder &s, const xparams _xparams = alglib::xdefault);
dfbuildergetprogress function/************************************************************************* This function is an alias for dfbuilderpeekprogress(), left in ALGLIB for backward compatibility reasons. -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/double dfbuildergetprogress(const decisionforestbuilder &s, const xparams _xparams = alglib::xdefault);
dfbuilderpeekprogress function/************************************************************************* This function is used to peek into decision forest construction process from some other thread and get current progress indicator. It returns value in [0,1]. INPUT PARAMETERS: S - decision forest builder object used to build forest in some other thread RESULT: progress value, in [0,1] -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/double dfbuilderpeekprogress(const decisionforestbuilder &s, const xparams _xparams = alglib::xdefault);
dfbuildersetdataset function/************************************************************************* This subroutine adds dense dataset to the internal storage of the builder object. Specifying your dataset in the dense format means that the dense version of the forest construction algorithm will be invoked. INPUT PARAMETERS: S - decision forest builder object XY - array[NPoints,NVars+1] (minimum size; actual size can be larger, only leading part is used anyway), dataset: * first NVars elements of each row store values of the independent variables * last column store class number (in 0...NClasses-1) or real value of the dependent variable NPoints - number of rows in the dataset, NPoints>=1 NVars - number of independent variables, NVars>=1 NClasses - indicates type of the problem being solved: * NClasses>=2 means that classification problem is solved (last column of the dataset stores class number) * NClasses=1 means that regression problem is solved (last column of the dataset stores variable value) OUTPUT PARAMETERS: S - decision forest builder -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/void dfbuildersetdataset(decisionforestbuilder &s, const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, const xparams _xparams = alglib::xdefault);
dfbuildersetimportancenone function/************************************************************************* This function tells decision forest construction algorithm to skip variable importance estimation. INPUT PARAMETERS: S - decision forest builder object OUTPUT PARAMETERS: S - decision forest builder object. Next call to the forest construction function will result in forest being built without variable importance estimation. -- ALGLIB -- Copyright 29.07.2019 by Bochkanov Sergey *************************************************************************/void dfbuildersetimportancenone(decisionforestbuilder &s, const xparams _xparams = alglib::xdefault);
dfbuildersetimportanceoobgini function/************************************************************************* This function tells decision forest construction algorithm to use out-of-bag version of Gini variable importance estimation (also known as OOB-MDI). This version of importance estimation algorithm analyzes mean decrease in impurity (MDI) on out-of-bag sample during splits. The result is divided by impurity at the root node in order to produce estimate in [0,1] range. Such estimates are fast to calculate and resistant to overfitting issues (thanks to the out-of-bag estimates used). However, OOB Gini rating has following downsides: * there exist some bias towards continuous and high-cardinality categorical variables * Gini rating allows us to order variables by importance, but it is hard to define importance of the variable by itself. NOTE: informally speaking, MDA (permutation importance) rating answers the question "what part of the model predictive power is ruined by permuting k-th variable?" while MDI tells us "what part of the model predictive power was achieved due to usage of k-th variable". Thus, MDA rates each variable independently at "0 to 1" scale while MDI (and OOB-MDI too) tends to divide "unit amount of importance" between several important variables. If all variables are equally important, they will have same MDI/OOB-MDI rating, equal (for OOB-MDI: roughly equal) to 1/NVars. However, roughly same picture will be produced for the "all variables provide information no one is critical" situation and for the "all variables are critical, drop any one, everything is ruined" situation. Contrary to that, MDA will rate critical variable as ~1.0 important, and important but non-critical variable will have less than unit rating. NOTE: quite an often MDA and MDI return same results. It generally happens on problems with low test set error (a few percents at most) and large enough training set to avoid overfitting. The difference between MDA, MDI and OOB-MDI becomes important only on "hard" tasks with high test set error and/or small training set. INPUT PARAMETERS: S - decision forest builder object OUTPUT PARAMETERS: S - decision forest builder object. Next call to the forest construction function will produce: * importance estimates in rep.varimportances field * variable ranks in rep.topvars field -- ALGLIB -- Copyright 29.07.2019 by Bochkanov Sergey *************************************************************************/void dfbuildersetimportanceoobgini(decisionforestbuilder &s, const xparams _xparams = alglib::xdefault);
dfbuildersetimportancepermutation function/************************************************************************* This function tells decision forest construction algorithm to use permutation variable importance estimator (also known as MDA). This version of importance estimation algorithm analyzes mean increase in out-of-bag sum of squared residuals after random permutation of J-th variable. The result is divided by error computed with all variables being perturbed in order to produce R-squared-like estimate in [0,1] range. Such estimate is slower to calculate than Gini-based rating because it needs multiple inference runs for each of variables being studied. ALGLIB uses parallelized and highly optimized algorithm which analyzes path through the decision tree and allows to handle most perturbations in O(1) time; nevertheless, requesting MDA importances may increase forest construction time from 10% to 200% (or more, if you have thousands of variables). However, MDA rating has following benefits over Gini-based ones: * no bias towards specific variable types * ability to directly evaluate "absolute" importance of some variable at "0 to 1" scale (contrary to Gini-based rating, which returns comparative importances). NOTE: informally speaking, MDA (permutation importance) rating answers the question "what part of the model predictive power is ruined by permuting k-th variable?" while MDI tells us "what part of the model predictive power was achieved due to usage of k-th variable". Thus, MDA rates each variable independently at "0 to 1" scale while MDI (and OOB-MDI too) tends to divide "unit amount of importance" between several important variables. If all variables are equally important, they will have same MDI/OOB-MDI rating, equal (for OOB-MDI: roughly equal) to 1/NVars. However, roughly same picture will be produced for the "all variables provide information no one is critical" situation and for the "all variables are critical, drop any one, everything is ruined" situation. Contrary to that, MDA will rate critical variable as ~1.0 important, and important but non-critical variable will have less than unit rating. NOTE: quite an often MDA and MDI return same results. It generally happens on problems with low test set error (a few percents at most) and large enough training set to avoid overfitting. The difference between MDA, MDI and OOB-MDI becomes important only on "hard" tasks with high test set error and/or small training set. INPUT PARAMETERS: S - decision forest builder object OUTPUT PARAMETERS: S - decision forest builder object. Next call to the forest construction function will produce: * importance estimates in rep.varimportances field * variable ranks in rep.topvars field -- ALGLIB -- Copyright 29.07.2019 by Bochkanov Sergey *************************************************************************/void dfbuildersetimportancepermutation(decisionforestbuilder &s, const xparams _xparams = alglib::xdefault);
dfbuildersetimportancetrngini function/************************************************************************* This function tells decision forest construction algorithm to use Gini impurity based variable importance estimation (also known as MDI). This version of importance estimation algorithm analyzes mean decrease in impurity (MDI) on training sample during splits. The result is divided by impurity at the root node in order to produce estimate in [0,1] range. Such estimates are fast to calculate and beautifully normalized (sum to one) but have following downsides: * They ALWAYS sum to 1.0, even if output is completely unpredictable. I.e. MDI allows to order variables by importance, but does not tell us about "absolute" importances of variables * there exist some bias towards continuous and high-cardinality categorical variables NOTE: informally speaking, MDA (permutation importance) rating answers the question "what part of the model predictive power is ruined by permuting k-th variable?" while MDI tells us "what part of the model predictive power was achieved due to usage of k-th variable". Thus, MDA rates each variable independently at "0 to 1" scale while MDI (and OOB-MDI too) tends to divide "unit amount of importance" between several important variables. If all variables are equally important, they will have same MDI/OOB-MDI rating, equal (for OOB-MDI: roughly equal) to 1/NVars. However, roughly same picture will be produced for the "all variables provide information no one is critical" situation and for the "all variables are critical, drop any one, everything is ruined" situation. Contrary to that, MDA will rate critical variable as ~1.0 important, and important but non-critical variable will have less than unit rating. NOTE: quite an often MDA and MDI return same results. It generally happens on problems with low test set error (a few percents at most) and large enough training set to avoid overfitting. The difference between MDA, MDI and OOB-MDI becomes important only on "hard" tasks with high test set error and/or small training set. INPUT PARAMETERS: S - decision forest builder object OUTPUT PARAMETERS: S - decision forest builder object. Next call to the forest construction function will produce: * importance estimates in rep.varimportances field * variable ranks in rep.topvars field -- ALGLIB -- Copyright 29.07.2019 by Bochkanov Sergey *************************************************************************/void dfbuildersetimportancetrngini(decisionforestbuilder &s, const xparams _xparams = alglib::xdefault);
dfbuildersetrdfalgo function/************************************************************************* This function sets random decision forest construction algorithm. As for now, only one decision forest construction algorithm is supported - a dense "baseline" RDF algorithm. INPUT PARAMETERS: S - decision forest builder object AlgoType - algorithm type: * 0 = baseline dense RDF OUTPUT PARAMETERS: S - decision forest builder, see -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/void dfbuildersetrdfalgo(decisionforestbuilder &s, const ae_int_t algotype, const xparams _xparams = alglib::xdefault);
dfbuildersetrdfsplitstrength function/************************************************************************* This function sets split selection algorithm used by decision forest classifier. You may choose several algorithms, with different speed and quality of the results. INPUT PARAMETERS: S - decision forest builder object SplitStrength- split type: * 0 = split at the random position, fastest one * 1 = split at the middle of the range * 2 = strong split at the best point of the range (default) OUTPUT PARAMETERS: S - decision forest builder, see -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/void dfbuildersetrdfsplitstrength(decisionforestbuilder &s, const ae_int_t splitstrength, const xparams _xparams = alglib::xdefault);
dfbuildersetrndvars function/************************************************************************* This function sets number of variables (in [1,NVars] range) used by decision forest construction algorithm. The default option is to use roughly sqrt(NVars) variables. INPUT PARAMETERS: S - decision forest builder object RndVars - number of randomly selected variables; values outside of [1,NVars] range are silently clipped. OUTPUT PARAMETERS: S - decision forest builder -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/void dfbuildersetrndvars(decisionforestbuilder &s, const ae_int_t rndvars, const xparams _xparams = alglib::xdefault);
dfbuildersetrndvarsauto function/************************************************************************* This function tells decision forest builder to automatically choose number of variables used by decision forest construction algorithm. Roughly sqrt(NVars) variables will be used. INPUT PARAMETERS: S - decision forest builder object OUTPUT PARAMETERS: S - decision forest builder -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/void dfbuildersetrndvarsauto(decisionforestbuilder &s, const xparams _xparams = alglib::xdefault);
dfbuildersetrndvarsratio function/************************************************************************* This function sets number of variables used by decision forest construction algorithm as a fraction of total variable count (0,1) range. The default option is to use roughly sqrt(NVars) variables. INPUT PARAMETERS: S - decision forest builder object F - round(NVars*F) variables are selected OUTPUT PARAMETERS: S - decision forest builder -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/void dfbuildersetrndvarsratio(decisionforestbuilder &s, const double f, const xparams _xparams = alglib::xdefault);
dfbuildersetseed function/************************************************************************* This function sets seed used by internal RNG for random subsampling and random selection of variable subsets. By default random seed is used, i.e. every time you build decision forest, we seed generator with new value obtained from system-wide RNG. Thus, decision forest builder returns non-deterministic results. You can change such behavior by specyfing fixed positive seed value. INPUT PARAMETERS: S - decision forest builder object SeedVal - seed value: * positive values are used for seeding RNG with fixed seed, i.e. subsequent runs on same data will return same decision forests * non-positive seed means that random seed is used for every run of builder, i.e. subsequent runs on same datasets will return slightly different decision forests OUTPUT PARAMETERS: S - decision forest builder, see -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/void dfbuildersetseed(decisionforestbuilder &s, const ae_int_t seedval, const xparams _xparams = alglib::xdefault);
dfbuildersetsubsampleratio function/************************************************************************* This function sets size of dataset subsample generated the decision forest construction algorithm. Size is specified as a fraction of total dataset size. The default option is to use 50% of the dataset for training, 50% for the OOB estimates. You can decrease fraction F down to 10%, 1% or even below in order to reduce overfitting. INPUT PARAMETERS: S - decision forest builder object F - fraction of the dataset to use, in (0,1] range. Values outside of this range will be silently clipped. At least one element is always selected for the training set. OUTPUT PARAMETERS: S - decision forest builder -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/void dfbuildersetsubsampleratio(decisionforestbuilder &s, const double f, const xparams _xparams = alglib::xdefault);
dfbuildrandomdecisionforest function/************************************************************************* This subroutine builds random decision forest. --------- DEPRECATED VERSION! USE DECISION FOREST BUILDER OBJECT --------- -- ALGLIB -- Copyright 19.02.2009 by Bochkanov Sergey *************************************************************************/void dfbuildrandomdecisionforest(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, const ae_int_t ntrees, const double r, ae_int_t &info, decisionforest &df, dfreport &rep, const xparams _xparams = alglib::xdefault);
dfbuildrandomdecisionforestx1 function/************************************************************************* This subroutine builds random decision forest. --------- DEPRECATED VERSION! USE DECISION FOREST BUILDER OBJECT --------- -- ALGLIB -- Copyright 19.02.2009 by Bochkanov Sergey *************************************************************************/void dfbuildrandomdecisionforestx1(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, const ae_int_t ntrees, const ae_int_t nrndvars, const double r, ae_int_t &info, decisionforest &df, dfreport &rep, const xparams _xparams = alglib::xdefault);
dfclassify function/************************************************************************* This function returns most probable class number for an input X. It is same as calling dfprocess(model,x,y), then determining i=argmax(y[i]) and returning i. A class number in [0,NOut) range in returned for classification problems, -1 is returned when this function is called for regression problems. IMPORTANT: this function is thread-unsafe and modifies internal structures of the model! You can not use same model object for parallel evaluation from several threads. Use dftsprocess() with independent thread-local buffers, if you need thread-safe evaluation. INPUT PARAMETERS: Model - decision forest model X - input vector, array[0..NVars-1]. RESULT: class number, -1 for regression tasks -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/ae_int_t dfclassify(decisionforest &model, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
dfcreatebuffer function/************************************************************************* This function creates buffer structure which can be used to perform parallel inference requests. DF subpackage provides two sets of computing functions - ones which use internal buffer of DF model (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 Model - DF model which is associated with newly created buffer OUTPUT PARAMETERS Buf - external buffer. IMPORTANT: buffer object should be used only with model 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 the model structure. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void dfcreatebuffer(const decisionforest &model, decisionforestbuffer &buf, const xparams _xparams = alglib::xdefault);
dfprocess function/************************************************************************* Inference using decision forest IMPORTANT: this function is thread-unsafe and may modify internal structures of the model! You can not use same model object for parallel evaluation from several threads. Use dftsprocess() with independent thread-local buffers if you need thread-safe evaluation. INPUT PARAMETERS: DF - decision forest model X - input vector, array[NVars] Y - possibly preallocated buffer, reallocated if too small OUTPUT PARAMETERS: Y - result. Regression estimate when solving regression task, vector of posterior probabilities for classification task. See also DFProcessI. -- ALGLIB -- Copyright 16.02.2009 by Bochkanov Sergey *************************************************************************/void dfprocess(const decisionforest &df, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
dfprocess0 function/************************************************************************* This function returns first component of the inferred vector (i.e. one with index #0). It is a convenience wrapper for dfprocess() intended for either: * 1-dimensional regression problems * 2-class classification problems In the former case this function returns inference result as scalar, which is definitely more convenient that wrapping it as vector. In the latter case it returns probability of object belonging to class #0. If you call it for anything different from two cases above, it will work as defined, i.e. return y[0], although it is of less use in such cases. IMPORTANT: this function is thread-unsafe and modifies internal structures of the model! You can not use same model object for parallel evaluation from several threads. Use dftsprocess() with independent thread-local buffers, if you need thread-safe evaluation. INPUT PARAMETERS: Model - DF model X - input vector, array[0..NVars-1]. RESULT: Y[0] -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/double dfprocess0(decisionforest &model, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
dfprocessi function/************************************************************************* 'interactive' variant of DFProcess for languages like Python which support constructs like "Y = DFProcessI(DF,X)" 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. IMPORTANT: this function is thread-unsafe and may modify internal structures of the model! You can not use same model object for parallel evaluation from several threads. Use dftsprocess() with independent thread-local buffers if you need thread-safe evaluation. -- ALGLIB -- Copyright 28.02.2010 by Bochkanov Sergey *************************************************************************/void dfprocessi(const decisionforest &df, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
dfrelclserror function/************************************************************************* Relative classification error on the test set INPUT PARAMETERS: DF - decision forest model XY - test set NPoints - test set size RESULT: percent of incorrectly classified cases. Zero if model solves regression task. -- ALGLIB -- Copyright 16.02.2009 by Bochkanov Sergey *************************************************************************/double dfrelclserror(const decisionforest &df, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
dfrmserror function/************************************************************************* RMS error on the test set INPUT PARAMETERS: DF - decision forest model XY - test set NPoints - test set size RESULT: root mean square error. Its meaning for regression task is obvious. As for classification task, RMS error means error when estimating posterior probabilities. -- ALGLIB -- Copyright 16.02.2009 by Bochkanov Sergey *************************************************************************/double dfrmserror(const decisionforest &df, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
dfserialize function/************************************************************************* This function serializes data structure to string/stream. 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 a text or XML file. But you should not insert separators into the middle of the "words" nor should you change the 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 it in C# one, and vice versa. *************************************************************************/void dfserialize(const decisionforest &obj, std::string &s_out); void dfserialize(const decisionforest &obj, std::ostream &s_out);
dftsprocess function/************************************************************************* Inference using decision forest Thread-safe procesing using external buffer for temporaries. This function is thread-safe (i.e . you can use same DF model from multiple threads) as long as you use different buffer objects for different threads. INPUT PARAMETERS: DF - decision forest model Buf - buffer object, must be allocated specifically for this model with dfcreatebuffer(). X - input vector, array[NVars] Y - possibly preallocated buffer, reallocated if too small OUTPUT PARAMETERS: Y - result. Regression estimate when solving regression task, vector of posterior probabilities for classification task. See also DFProcessI. -- ALGLIB -- Copyright 16.02.2009 by Bochkanov Sergey *************************************************************************/void dftsprocess(const decisionforest &df, decisionforestbuffer &buf, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
dfunserialize function/************************************************************************* This function unserializes data structure from string/stream. *************************************************************************/void dfunserialize(const std::string &s_in, decisionforest &obj); void dfunserialize(const std::istream &s_in, decisionforest &obj);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// The very simple classification example: classify points (x,y) in 2D space
// as ones with x>=0 and ones with x<0 (y is ignored, but our classifier
// has to find out it).
//
// First, we have to create decision forest builder object, load dataset and
// specify training settings. Our dataset is specified as matrix, which has
// following format:
//
// x0 y0 class0
// x1 y1 class1
// x2 y2 class2
// ....
//
// Here xi and yi can be any values (and in fact you can have any number of
// independent variables), and classi MUST be integer number in [0,NClasses)
// range. In our example we denote points with x>=0 as class #0, and
// ones with negative xi as class #1.
//
// NOTE: if you want to solve regression problem, specify NClasses=1. In
// this case last column of xy can be any numeric value.
//
// For the sake of simplicity, our example includes only 4-point dataset.
// However, random forests are able to cope with extremely large datasets
// having millions of examples.
//
decisionforestbuilder builder;
ae_int_t nvars = 2;
ae_int_t nclasses = 2;
ae_int_t npoints = 4;
real_2d_array xy = "[[1,1,0],[1,-1,0],[-1,1,1],[-1,-1,1]]";
dfbuildercreate(builder);
dfbuildersetdataset(builder, xy, npoints, nvars, nclasses);
// in our example we train decision forest using full sample - it allows us
// to get zero classification error. However, in practical applications smaller
// values are used: 50%, 25%, 5% or even less.
dfbuildersetsubsampleratio(builder, 1.0);
// we train random forest with just one tree; again, in real life situations
// you typically need from 50 to 500 trees.
ae_int_t ntrees = 1;
decisionforest forest;
dfreport rep;
dfbuilderbuildrandomforest(builder, ntrees, forest, rep);
// with such settings (100% of the training set is used) you can expect
// zero classification error. Beautiful results, but remember - in real life
// you do not need zero TRAINING SET error, you need good generalization.
printf("%.4f\n", double(rep.relclserror)); // EXPECTED: 0.0000
// now, let's perform some simple processing with dfprocess()
real_1d_array x = "[+1,0]";
real_1d_array y = "[]";
dfprocess(forest, x, y);
printf("%s\n", y.tostring(3).c_str()); // EXPECTED: [+1,0]
// another option is to use dfprocess0() which returns just first component
// of the output vector y. ideal for regression problems and binary classifiers.
double y0;
y0 = dfprocess0(forest, x);
printf("%.3f\n", double(y0)); // EXPECTED: 1.000
// finally, you can use dfclassify() which returns most probable class index (i.e. argmax y[i]).
ae_int_t i;
i = dfclassify(forest, x);
printf("%d\n", int(i)); // EXPECTED: 0
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// The very simple regression example: model f(x,y)=x+y
//
// First, we have to create DF builder object, load dataset and specify
// training settings. Our dataset is specified as matrix, which has following
// format:
//
// x0 y0 f0
// x1 y1 f1
// x2 y2 f2
// ....
//
// Here xi and yi can be any values, and fi is a dependent function value.
//
// NOTE: you can also solve classification problems with DF models, see
// another example for this unit.
//
decisionforestbuilder builder;
ae_int_t nvars = 2;
ae_int_t nclasses = 1;
ae_int_t npoints = 4;
real_2d_array xy = "[[1,1,+2],[1,-1,0],[-1,1,0],[-1,-1,-2]]";
dfbuildercreate(builder);
dfbuildersetdataset(builder, xy, npoints, nvars, nclasses);
// in our example we train decision forest using full sample - it allows us
// to get zero classification error. However, in practical applications smaller
// values are used: 50%, 25%, 5% or even less.
dfbuildersetsubsampleratio(builder, 1.0);
// we train random forest with just one tree; again, in real life situations
// you typically need from 50 to 500 trees.
ae_int_t ntrees = 1;
decisionforest model;
dfreport rep;
dfbuilderbuildrandomforest(builder, ntrees, model, rep);
// with such settings (full sample is used) you can expect zero RMS error on the
// training set. Beautiful results, but remember - in real life you do not
// need zero TRAINING SET error, you need good generalization.
printf("%.4f\n", double(rep.rmserror)); // EXPECTED: 0.0000
// now, let's perform some simple processing with dfprocess()
real_1d_array x = "[+1,+1]";
real_1d_array y = "[]";
dfprocess(model, x, y);
printf("%s\n", y.tostring(3).c_str()); // EXPECTED: [+2]
// another option is to use dfprocess0() which returns just first component
// of the output vector y. ideal for regression problems and binary classifiers.
double y0;
y0 = dfprocess0(model, x);
printf("%.3f\n", double(y0)); // EXPECTED: 2.000
// there also exist another convenience function, dfclassify(),
// but it does not work for regression problems - it always returns -1.
ae_int_t i;
i = dfclassify(model, x);
printf("%d\n", int(i)); // EXPECTED: -1
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
directdensesolvers subpackage| solve_complex | Solving dense complex linear equations | |
| solve_complex_m | Solving complex matrix equations | |
| solve_hpd | Solving Hermitian positive definite linear equations | |
| solve_ls | Solving dense linear equations in the least squares sense | |
| solve_real | Solving dense linear equations | |
| solve_real_m | Solving dense linear matrix equations | |
| solve_spd | Solving symmetric positive definite linear equations |
densesolverlsreport class/************************************************************************* *************************************************************************/class densesolverlsreport { public: densesolverlsreport(); densesolverlsreport(const densesolverlsreport &rhs); densesolverlsreport& operator=(const densesolverlsreport &rhs); virtual ~densesolverlsreport(); ae_int_t terminationtype; double r2; real_2d_array cx; ae_int_t n; ae_int_t k; };
densesolverreport class/************************************************************************* *************************************************************************/class densesolverreport { public: densesolverreport(); densesolverreport(const densesolverreport &rhs); densesolverreport& operator=(const densesolverreport &rhs); virtual ~densesolverreport(); ae_int_t terminationtype; double r1; double rinf; };
cmatrixlusolve function/************************************************************************* Complex dense linear solver for A*x=b with complex N*N A given by its LU decomposition and N*1 vectors x and b. This is "slow-but-robust" version of the complex linear solver with additional features which add significant performance overhead. Faster version is CMatrixLUSolveFast() function. Algorithm features: * automatic detection of degenerate cases * O(N^2) complexity * condition number estimation No iterative refinement is provided because exact form of original matrix is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in 10-15x performance penalty when compared ! with "fast" version which just calls triangular solver. ! ! This performance penalty is insignificant when compared with ! cost of large LU decomposition. However, if you call this ! function many times for the same left side, this overhead ! BECOMES significant. It also becomes significant for small- ! scale problems. ! ! In such cases we strongly recommend you to use faster solver, ! CMatrixLUSolveFast() function. INPUT PARAMETERS LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result P - array[0..N-1], pivots array, CMatrixLU result N - size of A B - array[0..N-1], right part OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or exactly singular matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void cmatrixlusolve(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_1d_array &b, complex_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void cmatrixlusolve(const complex_2d_array &lua, const integer_1d_array &p, const complex_1d_array &b, complex_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixlusolvefast function/************************************************************************* Complex dense linear solver for A*x=b with N*N complex A given by its LU decomposition and N*1 vectors x and b. This is fast lightweight version of solver, which is significantly faster than CMatrixLUSolve(), but does not provide additional information (like condition numbers). Algorithm features: * O(N^2) complexity * no additional time-consuming features, just triangular solver INPUT PARAMETERS LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result P - array[0..N-1], pivots array, CMatrixLU result N - size of A B - array[0..N-1], right part OUTPUT PARAMETERS B - array[N]: * result=true => overwritten by solution * result=false => filled by zeros NOTE: unlike CMatrixLUSolve(), this function does NOT check for near-degeneracy of input matrix. It checks for EXACT degeneracy, because this check is easy to do. However, very badly conditioned matrices may went unnoticed. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/bool cmatrixlusolvefast(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, complex_1d_array &b, const xparams _xparams = alglib::xdefault); bool cmatrixlusolvefast(const complex_2d_array &lua, const integer_1d_array &p, complex_1d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixlusolvem function/************************************************************************* Dense solver for A*X=B with N*N complex A given by its LU decomposition, and N*M matrices X and B (multiple right sides). "Slow-but-feature-rich" version of the solver. Algorithm features: * automatic detection of degenerate cases * O(M*N^2) complexity * condition number estimation No iterative refinement is provided because exact form of original matrix is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in significant performance penalty when ! compared with "fast" version which just calls triangular ! solver. ! ! This performance penalty is especially apparent when you use ! ALGLIB parallel capabilities (condition number estimation is ! inherently sequential). It also becomes significant for ! small-scale problems. ! ! In such cases we strongly recommend you to use faster solver, ! CMatrixLUSolveMFast() function. INPUT PARAMETERS LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result P - array[0..N-1], pivots array, RMatrixLU result N - size of A B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or exactly singular matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N,M], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void cmatrixlusolvem(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, complex_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void cmatrixlusolvem(const complex_2d_array &lua, const integer_1d_array &p, const complex_2d_array &b, complex_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixlusolvemfast function/************************************************************************* Dense solver for A*X=B with N*N complex A given by its LU decomposition, and N*M matrices X and B (multiple right sides). "Fast-but-lightweight" version of the solver. Algorithm features: * O(M*N^2) complexity * no additional time-consuming features INPUT PARAMETERS LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result P - array[0..N-1], pivots array, RMatrixLU result N - size of A B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS B - array[N,M]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or exactly singular system ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/bool cmatrixlusolvemfast(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, complex_2d_array &b, const ae_int_t m, const xparams _xparams = alglib::xdefault); bool cmatrixlusolvemfast(const complex_2d_array &lua, const integer_1d_array &p, complex_2d_array &b, const xparams _xparams = alglib::xdefault);
cmatrixmixedsolve function/************************************************************************* Dense solver. Same as RMatrixMixedSolve(), but for complex matrices. Algorithm features: * automatic detection of degenerate cases * condition number estimation * iterative refinement * O(N^2) complexity INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result P - array[0..N-1], pivots array, CMatrixLU result N - size of A B - array[0..N-1], right part OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or exactly singular matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void cmatrixmixedsolve(const complex_2d_array &a, const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_1d_array &b, complex_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void cmatrixmixedsolve(const complex_2d_array &a, const complex_2d_array &lua, const integer_1d_array &p, const complex_1d_array &b, complex_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixmixedsolvem function/************************************************************************* Dense solver. Same as RMatrixMixedSolveM(), but for complex matrices. Algorithm features: * automatic detection of degenerate cases * condition number estimation * iterative refinement * O(M*N^2) complexity INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result P - array[0..N-1], pivots array, CMatrixLU result N - size of A B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or exactly singular matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N,M], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void cmatrixmixedsolvem(const complex_2d_array &a, const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, complex_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void cmatrixmixedsolvem(const complex_2d_array &a, const complex_2d_array &lua, const integer_1d_array &p, const complex_2d_array &b, complex_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixsolve function/************************************************************************* Complex dense solver for A*x=B with N*N complex matrix A and N*1 complex vectors x and b. "Slow-but-feature-rich" version of the solver. Algorithm features: * automatic detection of degenerate cases * condition number estimation * iterative refinement * O(N^3) complexity IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system ! and performs iterative refinement, which results in ! significant performance penalty when compared with "fast" ! version which just performs LU decomposition and calls ! triangular solver. ! ! This performance penalty is especially visible in the ! multithreaded mode, because both condition number estimation ! and iterative refinement are inherently sequential ! calculations. ! ! Thus, if you need high performance and if you are pretty sure ! that your system is well conditioned, we strongly recommend ! you to use faster solver, CMatrixSolveFast() function. INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A B - array[0..N-1], right part OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or exactly singular matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void cmatrixsolve(const complex_2d_array &a, const ae_int_t n, const complex_1d_array &b, complex_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void cmatrixsolve(const complex_2d_array &a, const complex_1d_array &b, complex_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixsolvefast function/************************************************************************* Complex dense solver for A*x=B with N*N complex matrix A and N*1 complex vectors x and b. "Fast-but-lightweight" version of the solver. Algorithm features: * O(N^3) complexity * no additional time consuming features, just triangular solver INPUT PARAMETERS: A - array[0..N-1,0..N-1], system matrix N - size of A B - array[0..N-1], right part OUTPUT PARAMETERS: B - array[N]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or exactly singular system ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/bool cmatrixsolvefast(const complex_2d_array &a, const ae_int_t n, complex_1d_array &b, const xparams _xparams = alglib::xdefault); bool cmatrixsolvefast(const complex_2d_array &a, complex_1d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixsolvem function/************************************************************************* Complex dense solver for A*X=B with N*N complex matrix A, N*M complex matrices X and B. "Slow-but-feature-rich" version which provides additional functions, at the cost of slower performance. Faster version may be invoked with CMatrixSolveMFast() function. Algorithm features: * automatic detection of degenerate cases * condition number estimation * iterative refinement * O(N^3+M*N^2) complexity IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system ! and performs iterative refinement, which results in ! significant performance penalty when compared with "fast" ! version which just performs LU decomposition and calls ! triangular solver. ! ! This performance penalty is especially visible in the ! multithreaded mode, because both condition number estimation ! and iterative refinement are inherently sequential ! calculations. ! ! Thus, if you need high performance and if you are pretty sure ! that your system is well conditioned, we strongly recommend ! you to use faster solver, CMatrixSolveMFast() function. INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A B - array[0..N-1,0..M-1], right part M - right part size RFS - iterative refinement switch: * True - refinement is used. Less performance, more precision. * False - refinement is not used. More performance, less precision. OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or exactly singular matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N,M], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void cmatrixsolvem(const complex_2d_array &a, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, const bool rfs, complex_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void cmatrixsolvem(const complex_2d_array &a, const complex_2d_array &b, const bool rfs, complex_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixsolvemfast function/************************************************************************* Complex dense solver for A*X=B with N*N complex matrix A, N*M complex matrices X and B. "Fast-but-lightweight" version which provides just triangular solver - and no additional functions like iterative refinement or condition number estimation. Algorithm features: * O(N^3+M*N^2) complexity * no additional time consuming functions INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS: B - array[N,M]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or exactly singular system ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 16.03.2015 by Bochkanov Sergey *************************************************************************/bool cmatrixsolvemfast(const complex_2d_array &a, const ae_int_t n, complex_2d_array &b, const ae_int_t m, const xparams _xparams = alglib::xdefault); bool cmatrixsolvemfast(const complex_2d_array &a, complex_2d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
hpdmatrixcholeskysolve function/************************************************************************* Dense solver for A*x=b with N*N Hermitian positive definite matrix A given by its Cholesky decomposition, and N*1 complex vectors x and b. This is "slow-but-feature-rich" version of the solver which estimates condition number of the system. Algorithm features: * automatic detection of degenerate cases * O(N^2) complexity * condition number estimation * matrix is represented by its upper or lower triangle No iterative refinement is provided because such partial representation of matrix does not allow efficient calculation of extra-precise matrix-vector products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in 10-15x performance penalty when compared ! with "fast" version which just calls triangular solver. ! ! This performance penalty is insignificant when compared with ! cost of large LU decomposition. However, if you call this ! function many times for the same left side, this overhead ! BECOMES significant. It also becomes significant for small- ! scale problems (N<50). ! ! In such cases we strongly recommend you to use faster solver, ! HPDMatrixCholeskySolveFast() function. INPUT PARAMETERS CHA - array[0..N-1,0..N-1], Cholesky decomposition, SPDMatrixCholesky result N - size of A IsUpper - what half of CHA is provided B - array[0..N-1], right part OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or indefinite matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void hpdmatrixcholeskysolve(const complex_2d_array &cha, const ae_int_t n, const bool isupper, const complex_1d_array &b, complex_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void hpdmatrixcholeskysolve(const complex_2d_array &cha, const bool isupper, const complex_1d_array &b, complex_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
hpdmatrixcholeskysolvefast function/************************************************************************* Dense solver for A*x=b with N*N Hermitian positive definite matrix A given by its Cholesky decomposition, and N*1 complex vectors x and b. This is "fast-but-lightweight" version of the solver. Algorithm features: * O(N^2) complexity * matrix is represented by its upper or lower triangle * no additional time-consuming features INPUT PARAMETERS CHA - array[0..N-1,0..N-1], Cholesky decomposition, SPDMatrixCholesky result N - size of A IsUpper - what half of CHA is provided B - array[0..N-1], right part OUTPUT PARAMETERS B - array[N]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or indefinite system -- ALGLIB -- Copyright 18.03.2015 by Bochkanov Sergey *************************************************************************/bool hpdmatrixcholeskysolvefast(const complex_2d_array &cha, const ae_int_t n, const bool isupper, complex_1d_array &b, const xparams _xparams = alglib::xdefault); bool hpdmatrixcholeskysolvefast(const complex_2d_array &cha, const bool isupper, complex_1d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
hpdmatrixcholeskysolvem function/************************************************************************* Dense solver for A*X=B with N*N Hermitian positive definite matrix A given by its Cholesky decomposition and N*M complex matrices X and B. This is "slow-but-feature-rich" version of the solver which, in addition to the solution, estimates condition number of the system. Algorithm features: * automatic detection of degenerate cases * O(M*N^2) complexity * condition number estimation * matrix is represented by its upper or lower triangle No iterative refinement is provided because such partial representation of matrix does not allow efficient calculation of extra-precise matrix-vector products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in significant performance penalty when ! compared with "fast" version which just calls triangular ! solver. Amount of overhead introduced depends on M (the ! larger - the more efficient). ! ! This performance penalty is insignificant when compared with ! cost of large Cholesky decomposition. However, if you call ! this function many times for the same left side, this ! overhead BECOMES significant. It also becomes significant ! for small-scale problems (N<50). ! ! In such cases we strongly recommend you to use faster solver, ! HPDMatrixCholeskySolveMFast() function. INPUT PARAMETERS CHA - array[N,N], Cholesky decomposition, HPDMatrixCholesky result N - size of CHA IsUpper - what half of CHA is provided B - array[N,M], right part M - right part size OUTPUT PARAMETERS: Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or indefinite matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void hpdmatrixcholeskysolvem(const complex_2d_array &cha, const ae_int_t n, const bool isupper, const complex_2d_array &b, const ae_int_t m, complex_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void hpdmatrixcholeskysolvem(const complex_2d_array &cha, const bool isupper, const complex_2d_array &b, complex_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
hpdmatrixcholeskysolvemfast function/************************************************************************* Dense solver for A*X=B with N*N Hermitian positive definite matrix A given by its Cholesky decomposition and N*M complex matrices X and B. This is "fast-but-lightweight" version of the solver. Algorithm features: * O(M*N^2) complexity * matrix is represented by its upper or lower triangle * no additional time-consuming features INPUT PARAMETERS CHA - array[N,N], Cholesky decomposition, HPDMatrixCholesky result N - size of CHA IsUpper - what half of CHA is provided B - array[N,M], right part M - right part size OUTPUT PARAMETERS: B - array[N]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or indefinite system -- ALGLIB -- Copyright 18.03.2015 by Bochkanov Sergey *************************************************************************/bool hpdmatrixcholeskysolvemfast(const complex_2d_array &cha, const ae_int_t n, const bool isupper, complex_2d_array &b, const ae_int_t m, const xparams _xparams = alglib::xdefault); bool hpdmatrixcholeskysolvemfast(const complex_2d_array &cha, const bool isupper, complex_2d_array &b, const xparams _xparams = alglib::xdefault);
hpdmatrixsolve function/************************************************************************* Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and N*1 complex vectors x and b. "Slow-but-feature-rich" version of the solver. Algorithm features: * automatic detection of degenerate cases * condition number estimation * O(N^3) complexity * matrix is represented by its upper or lower triangle No iterative refinement is provided because such partial representation of matrix does not allow efficient calculation of extra-precise matrix-vector products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in significant performance penalty when ! compared with "fast" version which just performs Cholesky ! decomposition and calls triangular solver. ! ! This performance penalty is especially visible in the ! multithreaded mode, because both condition number estimation ! and iterative refinement are inherently sequential ! calculations. ! ! Thus, if you need high performance and if you are pretty sure ! that your system is well conditioned, we strongly recommend ! you to use faster solver, HPDMatrixSolveFast() function. INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A IsUpper - what half of A is provided B - array[0..N-1], right part OUTPUT PARAMETERS Rep - same as in RMatrixSolve X - same as in RMatrixSolve ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void hpdmatrixsolve(const complex_2d_array &a, const ae_int_t n, const bool isupper, const complex_1d_array &b, complex_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void hpdmatrixsolve(const complex_2d_array &a, const bool isupper, const complex_1d_array &b, complex_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
hpdmatrixsolvefast function/************************************************************************* Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and N*1 complex vectors x and b. "Fast-but-lightweight" version of the solver without additional functions. Algorithm features: * O(N^3) complexity * matrix is represented by its upper or lower triangle * no additional time consuming functions INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A IsUpper - what half of A is provided B - array[0..N-1], right part OUTPUT PARAMETERS B - array[0..N-1]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or indefinite system ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 17.03.2015 by Bochkanov Sergey *************************************************************************/bool hpdmatrixsolvefast(const complex_2d_array &a, const ae_int_t n, const bool isupper, complex_1d_array &b, const xparams _xparams = alglib::xdefault); bool hpdmatrixsolvefast(const complex_2d_array &a, const bool isupper, complex_1d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
hpdmatrixsolvem function/************************************************************************* Dense solver for A*X=B, with N*N Hermitian positive definite matrix A and N*M complex matrices X and B. "Slow-but-feature-rich" version of the solver. Algorithm features: * automatic detection of degenerate cases * condition number estimation * O(N^3+M*N^2) complexity * matrix is represented by its upper or lower triangle No iterative refinement is provided because such partial representation of matrix does not allow efficient calculation of extra-precise matrix-vector products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in significant performance penalty when ! compared with "fast" version which just calls triangular ! solver. ! ! This performance penalty is especially apparent when you use ! ALGLIB parallel capabilities (condition number estimation is ! inherently sequential). It also becomes significant for ! small-scale problems (N<100). ! ! In such cases we strongly recommend you to use faster solver, ! HPDMatrixSolveMFast() function. INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A IsUpper - what half of A is provided B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS Rep - same as in RMatrixSolve X - same as in RMatrixSolve ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void hpdmatrixsolvem(const complex_2d_array &a, const ae_int_t n, const bool isupper, const complex_2d_array &b, const ae_int_t m, complex_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void hpdmatrixsolvem(const complex_2d_array &a, const bool isupper, const complex_2d_array &b, complex_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
hpdmatrixsolvemfast function/************************************************************************* Dense solver for A*X=B, with N*N Hermitian positive definite matrix A and N*M complex matrices X and B. "Fast-but-lightweight" version of the solver. Algorithm features: * O(N^3+M*N^2) complexity * matrix is represented by its upper or lower triangle * no additional time consuming features like condition number estimation INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A IsUpper - what half of A is provided B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS B - array[0..N-1]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or indefinite system ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 17.03.2015 by Bochkanov Sergey *************************************************************************/bool hpdmatrixsolvemfast(const complex_2d_array &a, const ae_int_t n, const bool isupper, complex_2d_array &b, const ae_int_t m, const xparams _xparams = alglib::xdefault); bool hpdmatrixsolvemfast(const complex_2d_array &a, const bool isupper, complex_2d_array &b, const xparams _xparams = alglib::xdefault);
rmatrixlusolve function/************************************************************************* Dense solver. This subroutine solves a system A*x=b, where A is NxN non-denegerate real matrix given by its LU decomposition, x and b are real vectors. This is "slow-but-robust" version of the linear LU-based solver. Faster version is RMatrixLUSolveFast() function. Algorithm features: * automatic detection of degenerate cases * O(N^2) complexity * condition number estimation No iterative refinement is provided because exact form of original matrix is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in 10-15x performance penalty when compared ! with "fast" version which just calls triangular solver. ! ! This performance penalty is insignificant when compared with ! cost of large LU decomposition. However, if you call this ! function many times for the same left side, this overhead ! BECOMES significant. It also becomes significant for small- ! scale problems. ! ! In such cases we strongly recommend you to use faster solver, ! RMatrixLUSolveFast() function. INPUT PARAMETERS LUA - array[N,N], LU decomposition, RMatrixLU result P - array[N], pivots array, RMatrixLU result N - size of A B - array[N], right part OUTPUT PARAMETERS Rep - additional report, the following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void rmatrixlusolve(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_1d_array &b, real_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void rmatrixlusolve(const real_2d_array &lua, const integer_1d_array &p, const real_1d_array &b, real_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixlusolvefast function/************************************************************************* Dense solver. This subroutine solves a system A*x=b, where A is NxN non-denegerate real matrix given by its LU decomposition, x and b are real vectors. This is "fast-without-any-checks" version of the linear LU-based solver. Slower but more robust version is RMatrixLUSolve() function. Algorithm features: * O(N^2) complexity * fast algorithm without ANY additional checks, just triangular solver INPUT PARAMETERS LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result P - array[0..N-1], pivots array, RMatrixLU result N - size of A B - array[0..N-1], right part OUTPUT PARAMETERS B - array[N]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or exactly singular system -- ALGLIB -- Copyright 18.03.2015 by Bochkanov Sergey *************************************************************************/bool rmatrixlusolvefast(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, real_1d_array &b, const xparams _xparams = alglib::xdefault); bool rmatrixlusolvefast(const real_2d_array &lua, const integer_1d_array &p, real_1d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixlusolvem function/************************************************************************* Dense solver. Similar to RMatrixLUSolve() but solves task with multiple right parts (where b and x are NxM matrices). This is "robust-but-slow" version of LU-based solver which performs additional checks for non-degeneracy of inputs (condition number estimation). If you need best performance, use "fast-without-any-checks" version, RMatrixLUSolveMFast(). Algorithm features: * automatic detection of degenerate cases * O(M*N^2) complexity * condition number estimation No iterative refinement is provided because exact form of original matrix is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in significant performance penalty when ! compared with "fast" version which just calls triangular ! solver. ! ! This performance penalty is especially apparent when you use ! ALGLIB parallel capabilities (condition number estimation is ! inherently sequential). It also becomes significant for ! small-scale problems. ! ! In such cases we strongly recommend you to use faster solver, ! RMatrixLUSolveMFast() function. INPUT PARAMETERS LUA - array[N,N], LU decomposition, RMatrixLU result P - array[N], pivots array, RMatrixLU result N - size of A B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N,M], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void rmatrixlusolvem(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_2d_array &b, const ae_int_t m, real_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void rmatrixlusolvem(const real_2d_array &lua, const integer_1d_array &p, const real_2d_array &b, real_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixlusolvemfast function/************************************************************************* Dense solver. Similar to RMatrixLUSolve() but solves task with multiple right parts, where b and x are NxM matrices. This is "fast-without-any-checks" version of LU-based solver. It does not estimate condition number of a system, so it is extremely fast. If you need better detection of near-degenerate cases, use RMatrixLUSolveM() function. Algorithm features: * O(M*N^2) complexity * fast algorithm without ANY additional checks, just triangular solver INPUT PARAMETERS: LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result P - array[0..N-1], pivots array, RMatrixLU result N - size of A B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS: B - array[N,M]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or exactly singular system ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 18.03.2015 by Bochkanov Sergey *************************************************************************/bool rmatrixlusolvemfast(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, real_2d_array &b, const ae_int_t m, const xparams _xparams = alglib::xdefault); bool rmatrixlusolvemfast(const real_2d_array &lua, const integer_1d_array &p, real_2d_array &b, const xparams _xparams = alglib::xdefault);
rmatrixmixedsolve function/************************************************************************* Dense solver. This subroutine solves a system A*x=b, where BOTH ORIGINAL A AND ITS LU DECOMPOSITION ARE KNOWN. You can use it if for some reasons you have both A and its LU decomposition. Algorithm features: * automatic detection of degenerate cases * condition number estimation * iterative refinement * O(N^2) complexity INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result P - array[0..N-1], pivots array, RMatrixLU result N - size of A B - array[0..N-1], right part OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void rmatrixmixedsolve(const real_2d_array &a, const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_1d_array &b, real_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void rmatrixmixedsolve(const real_2d_array &a, const real_2d_array &lua, const integer_1d_array &p, const real_1d_array &b, real_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixmixedsolvem function/************************************************************************* Dense solver. Similar to RMatrixMixedSolve() but solves task with multiple right parts (where b and x are NxM matrices). Algorithm features: * automatic detection of degenerate cases * condition number estimation * iterative refinement * O(M*N^2) complexity INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result P - array[0..N-1], pivots array, RMatrixLU result N - size of A B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N,M], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void rmatrixmixedsolvem(const real_2d_array &a, const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_2d_array &b, const ae_int_t m, real_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void rmatrixmixedsolvem(const real_2d_array &a, const real_2d_array &lua, const integer_1d_array &p, const real_2d_array &b, real_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixsolve function/************************************************************************* Dense solver for A*x=b with N*N real matrix A and N*1 real vectorx x and b. This is "slow-but-feature rich" version of the linear solver. Faster version is RMatrixSolveFast() function. Algorithm features: * automatic detection of degenerate cases * condition number estimation * iterative refinement * O(N^3) complexity IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system ! and performs iterative refinement, which results in ! significant performance penalty when compared with "fast" ! version which just performs LU decomposition and calls ! triangular solver. ! ! This performance penalty is especially visible in the ! multithreaded mode, because both condition number estimation ! and iterative refinement are inherently sequential ! calculations. It is also very significant on small matrices. ! ! Thus, if you need high performance and if you are pretty sure ! that your system is well conditioned, we strongly recommend ! you to use faster solver, RMatrixSolveFast() function. INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A B - array[0..N-1], right part OUTPUT PARAMETERS Rep - additional report, the following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void rmatrixsolve(const real_2d_array &a, const ae_int_t n, const real_1d_array &b, real_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void rmatrixsolve(const real_2d_array &a, const real_1d_array &b, real_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixsolvefast function/************************************************************************* Dense solver. This subroutine solves a system A*x=b, where A is NxN non-denegerate real matrix, x and b are vectors. This is a "fast" version of linear solver which does NOT provide any additional functions like condition number estimation or iterative refinement. Algorithm features: * efficient algorithm O(N^3) complexity * no performance overhead from additional functionality If you need condition number estimation or iterative refinement, use more feature-rich version - RMatrixSolve(). INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A B - array[0..N-1], right part OUTPUT PARAMETERS B - array[N]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or exactly singular system ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 16.03.2015 by Bochkanov Sergey *************************************************************************/bool rmatrixsolvefast(const real_2d_array &a, const ae_int_t n, real_1d_array &b, const xparams _xparams = alglib::xdefault); bool rmatrixsolvefast(const real_2d_array &a, real_1d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixsolvels function/************************************************************************* Dense solver. This subroutine finds solution of the linear system A*X=B with non-square, possibly degenerate A. System is solved in the least squares sense, and general least squares solution X = X0 + CX*y which minimizes |A*X-B| is returned. If A is non-degenerate, solution in the usual sense is returned. Algorithm features: * automatic detection (and correct handling!) of degenerate cases * iterative refinement * O(N^3) complexity INPUT PARAMETERS A - array[0..NRows-1,0..NCols-1], system matrix NRows - vertical size of A NCols - horizontal size of A B - array[0..NCols-1], right part Threshold- a number in [0,1]. Singular values beyond Threshold*Largest are considered zero. Set it to 0.0, if you don't understand what it means, so the solver will choose good value on its own. OUTPUT PARAMETERS Rep - solver report, see below for more info X - array[0..N-1,0..M-1], it contains: * solution of A*X=B (even for singular A) * zeros, if SVD subroutine failed SOLVER REPORT Subroutine sets following fields of the Rep structure: * TerminationType is set to: * -4 for SVD failure * >0 for success * R2 reciprocal of condition number: 1/cond(A), 2-norm. * N = NCols * K dim(Null(A)) * CX array[0..N-1,0..K-1], kernel of A. Columns of CX store such vectors that A*CX[i]=0. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 24.08.2009 by Bochkanov Sergey *************************************************************************/void rmatrixsolvels(const real_2d_array &a, const ae_int_t nrows, const ae_int_t ncols, const real_1d_array &b, const double threshold, real_1d_array &x, densesolverlsreport &rep, const xparams _xparams = alglib::xdefault); void rmatrixsolvels(const real_2d_array &a, const real_1d_array &b, const double threshold, real_1d_array &x, densesolverlsreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixsolvem function/************************************************************************* Dense solver. Similar to RMatrixSolve() but solves task with multiple right parts (where b and x are NxM matrices). This is "slow-but-robust" version of linear solver with additional functionality like condition number estimation. There also exists faster version - RMatrixSolveMFast(). Algorithm features: * automatic detection of degenerate cases * condition number estimation * optional iterative refinement * O(N^3+M*N^2) complexity IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system ! and performs iterative refinement, which results in ! significant performance penalty when compared with "fast" ! version which just performs LU decomposition and calls ! triangular solver. ! ! This performance penalty is especially visible in the ! multithreaded mode, because both condition number estimation ! and iterative refinement are inherently sequential ! calculations. It also very significant on small matrices. ! ! Thus, if you need high performance and if you are pretty sure ! that your system is well conditioned, we strongly recommend ! you to use faster solver, RMatrixSolveMFast() function. INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A B - array[0..N-1,0..M-1], right part M - right part size RFS - iterative refinement switch: * True - refinement is used. Less performance, more precision. * False - refinement is not used. More performance, less precision. OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or exactly singular matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void rmatrixsolvem(const real_2d_array &a, const ae_int_t n, const real_2d_array &b, const ae_int_t m, const bool rfs, real_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void rmatrixsolvem(const real_2d_array &a, const real_2d_array &b, const bool rfs, real_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixsolvemfast function/************************************************************************* Dense solver. Similar to RMatrixSolve() but solves task with multiple right parts (where b and x are NxM matrices). This is "fast" version of linear solver which does NOT offer additional functions like condition number estimation or iterative refinement. Algorithm features: * O(N^3+M*N^2) complexity * no additional functionality, highest performance INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A B - array[0..N-1,0..M-1], right part M - right part size RFS - iterative refinement switch: * True - refinement is used. Less performance, more precision. * False - refinement is not used. More performance, less precision. OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm B - array[N]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True for well-conditioned matrix False for extremely badly conditioned or exactly singular problem ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/bool rmatrixsolvemfast(const real_2d_array &a, const ae_int_t n, real_2d_array &b, const ae_int_t m, const xparams _xparams = alglib::xdefault); bool rmatrixsolvemfast(const real_2d_array &a, real_2d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
spdmatrixcholeskysolve function/************************************************************************* Dense solver for A*x=b with N*N symmetric positive definite matrix A given by its Cholesky decomposition, and N*1 real vectors x and b. This is "slow- but-feature-rich" version of the solver which, in addition to the solution, performs condition number estimation. Algorithm features: * automatic detection of degenerate cases * O(N^2) complexity * condition number estimation * matrix is represented by its upper or lower triangle No iterative refinement is provided because such partial representation of matrix does not allow efficient calculation of extra-precise matrix-vector products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in 10-15x performance penalty when compared ! with "fast" version which just calls triangular solver. ! ! This performance penalty is insignificant when compared with ! cost of large LU decomposition. However, if you call this ! function many times for the same left side, this overhead ! BECOMES significant. It also becomes significant for small- ! scale problems (N<50). ! ! In such cases we strongly recommend you to use faster solver, ! SPDMatrixCholeskySolveFast() function. INPUT PARAMETERS CHA - array[N,N], Cholesky decomposition, SPDMatrixCholesky result N - size of A IsUpper - what half of CHA is provided B - array[N], right part OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or indefinite matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N]: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void spdmatrixcholeskysolve(const real_2d_array &cha, const ae_int_t n, const bool isupper, const real_1d_array &b, real_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void spdmatrixcholeskysolve(const real_2d_array &cha, const bool isupper, const real_1d_array &b, real_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
spdmatrixcholeskysolvefast function/************************************************************************* Dense solver for A*x=b with N*N symmetric positive definite matrix A given by its Cholesky decomposition, and N*1 real vectors x and b. This is "fast- but-lightweight" version of the solver. Algorithm features: * O(N^2) complexity * matrix is represented by its upper or lower triangle * no additional features INPUT PARAMETERS CHA - array[N,N], Cholesky decomposition, SPDMatrixCholesky result N - size of A IsUpper - what half of CHA is provided B - array[N], right part OUTPUT PARAMETERS B - array[N]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or exactly singular system -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/bool spdmatrixcholeskysolvefast(const real_2d_array &cha, const ae_int_t n, const bool isupper, real_1d_array &b, const xparams _xparams = alglib::xdefault); bool spdmatrixcholeskysolvefast(const real_2d_array &cha, const bool isupper, real_1d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
spdmatrixcholeskysolvem function/************************************************************************* Dense solver for A*X=B with N*N symmetric positive definite matrix A given by its Cholesky decomposition, and N*M vectors X and B. It is "slow-but- feature-rich" version of the solver which estimates condition number of the system. Algorithm features: * automatic detection of degenerate cases * O(M*N^2) complexity * condition number estimation * matrix is represented by its upper or lower triangle No iterative refinement is provided because such partial representation of matrix does not allow efficient calculation of extra-precise matrix-vector products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in significant performance penalty when ! compared with "fast" version which just calls triangular ! solver. Amount of overhead introduced depends on M (the ! larger - the more efficient). ! ! This performance penalty is insignificant when compared with ! cost of large LU decomposition. However, if you call this ! function many times for the same left side, this overhead ! BECOMES significant. It also becomes significant for small- ! scale problems (N<50). ! ! In such cases we strongly recommend you to use faster solver, ! SPDMatrixCholeskySolveMFast() function. INPUT PARAMETERS CHA - array[0..N-1,0..N-1], Cholesky decomposition, SPDMatrixCholesky result N - size of CHA IsUpper - what half of CHA is provided B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or indefinite matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N]: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void spdmatrixcholeskysolvem(const real_2d_array &cha, const ae_int_t n, const bool isupper, const real_2d_array &b, const ae_int_t m, real_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void spdmatrixcholeskysolvem(const real_2d_array &cha, const bool isupper, const real_2d_array &b, real_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
spdmatrixcholeskysolvemfast function/************************************************************************* Dense solver for A*X=B with N*N symmetric positive definite matrix A given by its Cholesky decomposition, and N*M vectors X and B. It is "fast-but- lightweight" version of the solver which just solves linear system, without any additional functions. Algorithm features: * O(M*N^2) complexity * matrix is represented by its upper or lower triangle * no additional functionality INPUT PARAMETERS CHA - array[N,N], Cholesky decomposition, SPDMatrixCholesky result N - size of CHA IsUpper - what half of CHA is provided B - array[N,M], right part M - right part size OUTPUT PARAMETERS B - array[N]: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or exactly singular system -- ALGLIB -- Copyright 18.03.2015 by Bochkanov Sergey *************************************************************************/bool spdmatrixcholeskysolvemfast(const real_2d_array &cha, const ae_int_t n, const bool isupper, real_2d_array &b, const ae_int_t m, const xparams _xparams = alglib::xdefault); bool spdmatrixcholeskysolvemfast(const real_2d_array &cha, const bool isupper, real_2d_array &b, const xparams _xparams = alglib::xdefault);
spdmatrixsolve function/************************************************************************* Dense linear solver for A*x=b with N*N real symmetric positive definite matrix A, N*1 vectors x and b. "Slow-but-feature-rich" version of the solver. Algorithm features: * automatic detection of degenerate cases * condition number estimation * O(N^3) complexity * matrix is represented by its upper or lower triangle No iterative refinement is provided because such partial representation of matrix does not allow efficient calculation of extra-precise matrix-vector products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in significant performance penalty when ! compared with "fast" version which just performs Cholesky ! decomposition and calls triangular solver. ! ! This performance penalty is especially visible in the ! multithreaded mode, because both condition number estimation ! and iterative refinement are inherently sequential ! calculations. ! ! Thus, if you need high performance and if you are pretty sure ! that your system is well conditioned, we strongly recommend ! you to use faster solver, SPDMatrixSolveFast() function. INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A IsUpper - what half of A is provided B - array[0..N-1], right part OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or indefinite matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void spdmatrixsolve(const real_2d_array &a, const ae_int_t n, const bool isupper, const real_1d_array &b, real_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void spdmatrixsolve(const real_2d_array &a, const bool isupper, const real_1d_array &b, real_1d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
spdmatrixsolvefast function/************************************************************************* Dense linear solver for A*x=b with N*N real symmetric positive definite matrix A, N*1 vectors x and b. "Fast-but-lightweight" version of the solver. Algorithm features: * O(N^3) complexity * matrix is represented by its upper or lower triangle * no additional time consuming features like condition number estimation INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A IsUpper - what half of A is provided B - array[0..N-1], right part OUTPUT PARAMETERS B - array[N], it contains: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or exactly singular system ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 17.03.2015 by Bochkanov Sergey *************************************************************************/bool spdmatrixsolvefast(const real_2d_array &a, const ae_int_t n, const bool isupper, real_1d_array &b, const xparams _xparams = alglib::xdefault); bool spdmatrixsolvefast(const real_2d_array &a, const bool isupper, real_1d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
spdmatrixsolvem function/************************************************************************* Dense solver for A*X=B with N*N symmetric positive definite matrix A, and N*M vectors X and B. It is "slow-but-feature-rich" version of the solver. Algorithm features: * automatic detection of degenerate cases * condition number estimation * O(N^3+M*N^2) complexity * matrix is represented by its upper or lower triangle No iterative refinement is provided because such partial representation of matrix does not allow efficient calculation of extra-precise matrix-vector products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you need iterative refinement. IMPORTANT: ! this function is NOT the most efficient linear solver provided ! by ALGLIB. It estimates condition number of linear system, ! which results in significant performance penalty when ! compared with "fast" version which just performs Cholesky ! decomposition and calls triangular solver. ! ! This performance penalty is especially visible in the ! multithreaded mode, because both condition number estimation ! and iterative refinement are inherently sequential ! calculations. ! ! Thus, if you need high performance and if you are pretty sure ! that your system is well conditioned, we strongly recommend ! you to use faster solver, SPDMatrixSolveMFast() function. INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A IsUpper - what half of A is provided B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS Rep - additional report, following fields are set: * rep.terminationtype >0 for success -3 for badly conditioned or indefinite matrix * rep.r1 condition number in 1-norm * rep.rinf condition number in inf-norm X - array[N,M], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/void spdmatrixsolvem(const real_2d_array &a, const ae_int_t n, const bool isupper, const real_2d_array &b, const ae_int_t m, real_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault); void spdmatrixsolvem(const real_2d_array &a, const bool isupper, const real_2d_array &b, real_2d_array &x, densesolverreport &rep, const xparams _xparams = alglib::xdefault);
spdmatrixsolvemfast function/************************************************************************* Dense solver for A*X=B with N*N symmetric positive definite matrix A, and N*M vectors X and B. It is "fast-but-lightweight" version of the solver. Algorithm features: * O(N^3+M*N^2) complexity * matrix is represented by its upper or lower triangle * no additional time consuming features INPUT PARAMETERS A - array[0..N-1,0..N-1], system matrix N - size of A IsUpper - what half of A is provided B - array[0..N-1,0..M-1], right part M - right part size OUTPUT PARAMETERS B - array[N,M], it contains: * result=true => overwritten by solution * result=false => filled by zeros RETURNS: True, if the system was solved False, for an extremely badly conditioned or exactly singular system ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 17.03.2015 by Bochkanov Sergey *************************************************************************/bool spdmatrixsolvemfast(const real_2d_array &a, const ae_int_t n, const bool isupper, real_2d_array &b, const ae_int_t m, const xparams _xparams = alglib::xdefault); bool spdmatrixsolvemfast(const real_2d_array &a, const bool isupper, real_2d_array &b, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates solution of a complex linear system
//
complex_1d_array x;
integer_1d_array pivots;
densesolverreport rep;
//
// First, solve A*x=b with a feature-rich cmatrixsolve() which supports iterative improvement
// and condition number estimation
//
complex_2d_array a = "[[-4,2i],[-1i,3]]";
complex_1d_array b = "[8i,5]";
cmatrixsolve(a, b, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [-1.0000i, 2.0000]
//
// Then, solve C*x=d with cmatrixsolvefast() which has lower overhead
//
complex_2d_array c = "[[3i,1],[2i,4]]";
complex_1d_array d = "[2,-2]";
cmatrixsolvefast(c, d);
printf("%s\n", d.tostring(4).c_str()); // EXPECTED: [-1.0000i, -1.0000]
//
// Sometimes you have LU decomposition of the system matrix readily
// available. In such cases it is possible to save a lot of time by
// passing precomputed LU factors to cmatrixlusolve(). The only
// downside of such approach is that iterative refinement is unavailable
// because original (unmodified) form of the system matrix is unknown
// to ALGLIB.
//
// However, if you have BOTH original matrix and its LU decomposition,
// it is possible to use cmatrixmixedsolve() which accepts both matrix
// itself and its factors, and uses original matrix to refine solution
// obtained with LU factors.
//
complex_2d_array e = "[[-3,4i],[2i,4]]";
complex_2d_array lue = "[[-3,4i],[2i,4]]";
complex_1d_array f = "[2i,0]";
cmatrixlu(lue, pivots);
cmatrixlusolve(lue, pivots, f, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [-2.0000i, -1.0000]
cmatrixmixedsolve(e, lue, pivots, f, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [-2.0000i, -1.0000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates solution of a dense complex matrix system
//
complex_2d_array x;
integer_1d_array pivots;
densesolverreport rep;
//
// First, solve A*X=B with a feature-rich cmatrixsolvem() which supports
// iterative improvement and condition number estimation. Here A is
// an N*N matrix, X is an N*M matrix, B is an N*M matrix.
//
complex_2d_array a = "[[4i,-2],[-1,3i]]";
complex_2d_array b = "[[8i,10i,4i],[5,1,-1]]";
cmatrixsolvem(a, b, true, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [[1.0000, 2.0000,1.0000],[-2.0000i,-1.0000i,0.0000]]
//
// Then, solve C*X=D with cmatrixsolvemfast() which has lower overhead
// due to condition number estimation and iterative refinement parts
// being dropped.
//
complex_2d_array c = "[[3,1],[2,4]]";
complex_2d_array d = "[[2,1],[-2,4]]";
cmatrixsolvemfast(c, d);
printf("%s\n", d.tostring(4).c_str()); // EXPECTED: [[1.0000,0.0000],[-1.0000,1.0000]]
//
// Sometimes you have LU decomposition of the system matrix readily
// available. In such cases it is possible to save a lot of time by
// passing precomputed LU factors to cmatrixlusolve(). The only
// downside of such approach is that iterative refinement is unavailable
// because original (unmodified) form of the system matrix is unknown
// to ALGLIB.
//
// However, if you have BOTH original matrix and its LU decomposition,
// it is possible to use cmatrixmixedsolve() which accepts both matrix
// itself and its factors, and uses original matrix to refine solution
// obtained with LU factors.
//
complex_2d_array e = "[[3,4],[2,4]]";
complex_2d_array lue = "[[3,4],[2,4]]";
complex_2d_array f = "[[2,5],[0,6]]";
cmatrixlu(lue, pivots);
cmatrixlusolvem(lue, pivots, f, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [[2.0000,-1.0000],[-1.0000,2.0000]]
cmatrixmixedsolvem(e, lue, pivots, f, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [[2.0000,-1.0000],[-1.0000,2.0000]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates solution of a Hermitian positive definite complex system
//
complex_1d_array x;
densesolverreport rep;
bool isupper = true;
//
// First, solve A*x=b with a feature-rich hpdmatrixsolve() which supports iterative improvement
// and condition number estimation
//
complex_2d_array a = "[[4,1i],[-1i,4]]";
complex_1d_array b = "[6,-9i]";
hpdmatrixsolve(a, isupper, b, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [1.0000, -2.0000i]
//
// Then, solve C*x=d with hpdmatrixsolvefast() which has lower overhead
//
complex_2d_array c = "[[3,-1i],[1i,3]]";
complex_1d_array d = "[-2i,-2]";
hpdmatrixsolvefast(c, isupper, d);
printf("%s\n", d.tostring(4).c_str()); // EXPECTED: [-1.0000i, -1.0000]
//
// Sometimes you have Cholesky decomposition of the system matrix readily
// available. In such cases it is possible to save a lot of time by
// passing precomputed Cholesky factor to hpdmatrixcholeskysolve(). The only
// downside of such approach is that iterative refinement is unavailable
// because original (unmodified) form of the system matrix is unknown
// to ALGLIB.
//
complex_2d_array e = "[[3,2],[2,3]]";
complex_1d_array f = "[4,1]";
hpdmatrixcholesky(e, isupper);
hpdmatrixcholeskysolve(e, isupper, f, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [2.0000, -1.0000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
real_1d_array x;
densesolverlsreport rep;
real_2d_array a = "[[4,2],[-1,3],[6,5]]";
real_1d_array b = "[8,5,16]";
rmatrixsolvels(a, b, 0.0, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [1.0000, 2.0000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates solution of a dense real linear system
//
real_1d_array x;
integer_1d_array pivots;
densesolverreport rep;
//
// First, solve A*x=b with a feature-rich rmatrixsolve() which supports iterative improvement
// and condition number estimation
//
real_2d_array a = "[[4,2],[-1,3]]";
real_1d_array b = "[8,5]";
rmatrixsolve(a, b, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [1.0000, 2.0000]
//
// Then, solve C*x=d with rmatrixsolvefast() which has lower overhead
//
real_2d_array c = "[[3,1],[2,4]]";
real_1d_array d = "[2,-2]";
rmatrixsolvefast(c, d);
printf("%s\n", d.tostring(4).c_str()); // EXPECTED: [1.0000, -1.0000]
//
// Sometimes you have LU decomposition of the system matrix readily
// available. In such cases it is possible to save a lot of time by
// passing precomputed LU factors to rmatrixlusolve(). The only
// downside of such approach is that iterative refinement is unavailable
// because original (unmodified) form of the system matrix is unknown
// to ALGLIB.
//
// However, if you have BOTH original matrix and its LU decomposition,
// it is possible to use rmatrixmixedsolve() which accepts both matrix
// itself and its factors, and uses original matrix to refine solution
// obtained with LU factors.
//
real_2d_array e = "[[3,4],[2,4]]";
real_2d_array lue = "[[3,4],[2,4]]";
real_1d_array f = "[2,0]";
rmatrixlu(lue, pivots);
rmatrixlusolve(lue, pivots, f, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [2.0000, -1.0000]
rmatrixmixedsolve(e, lue, pivots, f, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [2.0000, -1.0000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates solution of a dense real matrix system
//
real_2d_array x;
integer_1d_array pivots;
densesolverreport rep;
//
// First, solve A*X=B with a feature-rich rmatrixsolvem() which supports
// iterative improvement and condition number estimation. Here A is
// an N*N matrix, X is an N*M matrix, B is an N*M matrix.
//
real_2d_array a = "[[4,2],[-1,3]]";
real_2d_array b = "[[8,10,4],[5,1,-1]]";
rmatrixsolvem(a, b, true, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [[1.0000, 2.0000,1.0000],[2.0000,1.0000,0.0000]]
//
// Then, solve C*X=D with rmatrixsolvemfast() which has lower overhead
// due to condition number estimation and iterative refinement parts
// being dropped.
//
real_2d_array c = "[[3,1],[2,4]]";
real_2d_array d = "[[2,1],[-2,4]]";
rmatrixsolvemfast(c, d);
printf("%s\n", d.tostring(4).c_str()); // EXPECTED: [[1.0000,0.0000],[-1.0000,1.0000]]
//
// Sometimes you have LU decomposition of the system matrix readily
// available. In such cases it is possible to save a lot of time by
// passing precomputed LU factors to rmatrixlusolve(). The only
// downside of such approach is that iterative refinement is unavailable
// because original (unmodified) form of the system matrix is unknown
// to ALGLIB.
//
// However, if you have BOTH original matrix and its LU decomposition,
// it is possible to use rmatrixmixedsolve() which accepts both matrix
// itself and its factors, and uses original matrix to refine solution
// obtained with LU factors.
//
real_2d_array e = "[[3,4],[2,4]]";
real_2d_array lue = "[[3,4],[2,4]]";
real_2d_array f = "[[2,5],[0,6]]";
rmatrixlu(lue, pivots);
rmatrixlusolvem(lue, pivots, f, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [[2.0000,-1.0000],[-1.0000,2.0000]]
rmatrixmixedsolvem(e, lue, pivots, f, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [[2.0000,-1.0000],[-1.0000,2.0000]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates solution of a symmetric positive definite real system
//
real_1d_array x;
densesolverreport rep;
bool isupper = true;
//
// First, solve A*x=b with a feature-rich spdmatrixsolve() which supports iterative improvement
// and condition number estimation
//
real_2d_array a = "[[4,1],[1,4]]";
real_1d_array b = "[6,9]";
spdmatrixsolve(a, isupper, b, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [1.0000, 2.0000]
//
// Then, solve C*x=d with spdmatrixsolvefast() which has lower overhead
//
real_2d_array c = "[[3,1],[1,3]]";
real_1d_array d = "[2,-2]";
spdmatrixsolvefast(c, isupper, d);
printf("%s\n", d.tostring(4).c_str()); // EXPECTED: [1.0000, -1.0000]
//
// Sometimes you have Cholesky decomposition of the system matrix readily
// available. In such cases it is possible to save a lot of time by
// passing precomputed Cholesky factor to spdmatrixcholeskysolve(). The only
// downside of such approach is that iterative refinement is unavailable
// because original (unmodified) form of the system matrix is unknown
// to ALGLIB.
//
real_2d_array e = "[[3,2],[2,3]]";
real_1d_array f = "[4,1]";
spdmatrixcholesky(e, isupper);
spdmatrixcholeskysolve(e, isupper, f, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [2.0000, -1.0000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
directsparsesolvers subpackage| solvesks_d_1 | Solving low profile positive definite sparse systems with Skyline (SKS) solver | |
| sparse_solve | Solving general sparse linear systems | |
| sparse_solve_cholesky | Solving positive definite sparse linear systems with the supernodal Cholesky solver |
sparselusolve function/************************************************************************* Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real matrix A given by its LU factorization, N*1 vectors x and b. IMPORTANT: this solver requires input matrix to be in the CRS sparse storage format. An exception will be generated if you pass matrix in some other format (HASH or SKS). INPUT PARAMETERS A - LU factorization of the sparse matrix, must be NxN exactly in CRS storage format P, Q - pivot indexes from LU factorization N - size of A, N>0 B - array[0..N-1], right part OUTPUT PARAMETERS X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros Rep - solver report, following fields are set: * rep.terminationtype - solver status; >0 for success, set to -3 on failure (degenerate system). -- ALGLIB -- Copyright 26.12.2017 by Bochkanov Sergey *************************************************************************/void sparselusolve(const sparsematrix &a, const integer_1d_array &p, const integer_1d_array &q, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault);
sparsesolve function/************************************************************************* Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real matrix A, N*1 vectors x and b. Depending on ALGLIB edition (Free or Commercial, C++, C# or other), one of the following approaches can be used: * ALGLIB supernodal solver with static pivoting applied to a 2N*2N regularized augmented system, followed by iterative refinement. This solver is a recommended option because it provides the best speed and has the lowest memory requirements. Depending on the programming language and library edition (Free or Commercial), it can be a generic C implementation, generic C# code, C code with SIMD kernels. * sparse LU with dynamic pivoting for stability. Provides better accuracy at the cost of a significantly lower performance. Recommended only for extremely unstable problems. * COMMERCIAL EDITION: Performance Backend Library can be used, if linked/ loaded. See ALGLIB Reference Manual for the most actual information about supported backends. Different backends are optimized for different problem classes; for some problems, a backend library may outperform ALGLIB; for other problem types, ALGLIB DSS solver is superior. INPUT PARAMETERS A - sparse matrix, must be NxN exactly, any storage format B - array[N], right part SolverType- solver type to use: * 0 use the best solver. It is augmented system in the current version, but may change in future releases * 10 use 'default profile' of the supernodal solver with static pivoting. The 'default' profile is intended for systems with plenty of memory; it is optimized for the best convergence at the cost of increased RAM usage. Recommended option. * 11 use 'limited memory' profile of the supernodal solver with static pivoting. The limited-memory profile is intended for problems with millions of variables. On most systems it has the same convergence as the default profile, having somewhat worse results only for ill-conditioned systems. * 20 use sparse LU with dynamic pivoting for stability. Not intended for large-scale problems. OUTPUT PARAMETERS X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros Rep - solver report, following fields are set: * rep.terminationtype - solver status; >0 for success, set to -3 on failure (degenerate system). -- ALGLIB -- Copyright 18.11.2023 by Bochkanov Sergey *************************************************************************/void sparsesolve(const sparsematrix &a, const real_1d_array &b, const ae_int_t solvertype, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault); void sparsesolve(const sparsematrix &a, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
sparsesolvelsreg function/************************************************************************* Sparse linear least squares solver for A*x=b with general (nonsymmetric) N*N sparse real matrix A, N*1 vectors x and b. This function solves a regularized linear least squares problem of the form ( ) min ( |Ax-b|^2 + reg*|x|^2 ), with reg>=sqrt(MachineAccuracy) ( ) It can be used to solve both full rank and rank deficient systems. Depending on ALGLIB edition (Free or Commercial, C++, C# or other), one of the following approaches can be used: * ALGLIB supernodal solver with static pivoting applied to a 2N*2N regularized augmented system, followed by iterative refinement. This solver is a recommended option because it provides the best speed and has the lowest memory requirements. Depending on the programming language and library edition (Free or Commercial), it can be a generic C implementation, generic C# code, C code with SIMD kernels. * COMMERCIAL EDITION: Performance Backend Library can be used, if linked/ loaded. See ALGLIB Reference Manual for the most actual information about supported backends. Different backends are optimized for different problem classes; for some problems, a backend library may outperform ALGLIB; for other problem types, ALGLIB DSS solver is superior. INPUT PARAMETERS A - sparse MxN matrix, any storage format B - array[M], right part Reg - regularization coefficient, Reg>=sqrt(MachineAccuracy), lower values will be silently increased. SolverType- solver type to use: * 0 use the best solver. It is augmented system in the current version, but may change in future releases * 10 use 'default profile' of the supernodal solver with static pivoting. The 'default' profile is intended for systems with plenty of memory; it is optimized for the best convergence at the cost of increased RAM usage. Recommended option. * 11 use 'limited memory' profile of the supernodal solver with static pivoting. The limited-memory profile is intended for problems with millions of variables. On most systems it has the same convergence as the default profile, having somewhat worse results only for ill-conditioned systems. OUTPUT PARAMETERS X - array[N], least squares solution Rep - solver report, following fields are set: * rep.terminationtype - solver status; >0 for success. Present version of the solver does NOT returns negative completion codes because it does not fail. However, future ALGLIB versions may include solvers which return negative completion codes. -- ALGLIB -- Copyright 18.11.2023 by Bochkanov Sergey *************************************************************************/void sparsesolvelsreg(const sparsematrix &a, const real_1d_array &b, const double reg, const ae_int_t solvertype, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault); void sparsesolvelsreg(const sparsematrix &a, const real_1d_array &b, const double reg, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault);
sparsespdcholeskysolve function/************************************************************************* Sparse linear solver for A*x=b with N*N real symmetric positive definite matrix A given by its Cholesky decomposition, and N*1 vectors x and b. IMPORTANT: this solver requires input matrix to be in the SKS (Skyline) or CRS (compressed row storage) format. An exception will be generated if you pass matrix in some other format. INPUT PARAMETERS A - sparse NxN matrix stored in CRs or SKS format, must be NxN exactly IsUpper - which half of A is provided (another half is ignored) B - array[N], right part OUTPUT PARAMETERS X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros Rep - solver report, following fields are set: * rep.terminationtype - solver status; >0 for success, set to -3 on failure (degenerate or non-SPD system). -- ALGLIB -- Copyright 26.12.2017 by Bochkanov Sergey *************************************************************************/void sparsespdcholeskysolve(const sparsematrix &a, const bool isupper, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
sparsespdsolve function/************************************************************************* Sparse linear solver for A*x=b with N*N sparse real symmetric positive definite matrix A, N*1 vectors x and b. Depending on the ALGLIB edition (Free or Commercial, C++, C# or other), the following applies: * FREE EDITION: ALGLIB sparse solver can be used, a supernodal algorithm with serial implementation in generic C or generic C#. * COMMERCIAL EDITION: a parallel and SIMD-capable version of the ALGLIB sparse supernodal solver can be used. A C code with SIMD kernels callable from C++ and C#. * COMMERCIAL EDITION: Performance Backend Library can be used, if linked/ loaded. See ALGLIB Reference Manual for the most actual information about supported backends. Different backends are optimized for different problem classes; for some problems, a backend library can outperform ALGLIB; for other problem types, ALGLIB DSS solver can be superior. IMPORTANT: This function is preferred to one that works with explicitly given Cholesky factorization (sparsespdcholeskysolve). Some efficient linear solver backends do not return Cholesky factors, so doing explicit Cholesky followed by sparsespdcholeskysolve() means that these backends will never be activated. INPUT PARAMETERS A - sparse matrix, must be NxN exactly. Can be stored in any sparse storage format, CRS is preferred. IsUpper - which half of A is provided (another half is ignored). It is better to store the lower triangle because it allows us to avoid one transposition during internal conversion. B - array[N], right part OUTPUT PARAMETERS X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros Rep - solver report, following fields are set: * rep.terminationtype - solver status; >0 for success, set to -3 on failure (degenerate or non-SPD system). -- ALGLIB -- Copyright 26.12.2017 by Bochkanov Sergey *************************************************************************/void sparsespdsolve(const sparsematrix &a, const bool isupper, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
sparsespdsolvesks function/************************************************************************* Sparse linear solver for A*x=b with N*N sparse real symmetric positive definite matrix A, N*1 vectors x and b. This solver converts input matrix to SKS format, performs Cholesky factorization using SKS Cholesky subroutine (works well for limited bandwidth matrices) and uses sparse triangular solvers to get solution of the original system. IMPORTANT: this function is intended for low profile (variable band) linear systems with dense or nearly-dense bands. Only in such cases it provides some performance improvement over more general sparsrspdsolve(). If your system has high bandwidth or sparse band, the general sparsrspdsolve() is likely to be more efficient. INPUT PARAMETERS A - sparse matrix, must be NxN exactly IsUpper - which half of A is provided (another half is ignored) B - array[0..N-1], right part OUTPUT PARAMETERS X - array[N], it contains: * rep.terminationtype>0 => solution * rep.terminationtype=-3 => filled by zeros Rep - solver report, following fields are set: * rep.terminationtype - solver status; >0 for success, set to -3 on failure (degenerate or non-SPD system). -- ALGLIB -- Copyright 26.12.2017 by Bochkanov Sergey *************************************************************************/void sparsespdsolvesks(const sparsematrix &a, const bool isupper, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates creation/initialization of the sparse matrix
// in the SKS (Skyline) storage format and solution using SKS-based direct
// solver.
//
// NOTE: the SKS solver is intended for 'easy' tasks, i.e. low-profile positive
// definite systems (e.g. matrices with average bandwidth as low as 3),
// where it can avoid some overhead associated with more powerful supernodal
// Cholesky solver with AMD ordering.
//
// It is recommended to use more powerful solvers for more difficult problems:
// * sparsespdsolve() for larger sparse positive definite systems
// * sparsesolve() for general (nonsymmetric) linear systems
//
// First, we have to create matrix and initialize it. Matrix is created
// in the SKS format, using fixed bandwidth initialization function.
// Several points should be noted:
//
// 1. SKS sparse storage format also allows variable bandwidth matrices;
// we just do not want to overcomplicate this example.
//
// 2. SKS format requires you to specify matrix geometry prior to
// initialization of its elements with sparseset(). If you specified
// bandwidth=1, you can not change your mind afterwards and call
// sparseset() for non-existent elements.
//
// 3. Because SKS solver need just one triangle of SPD matrix, we can
// omit initialization of the lower triangle of our matrix.
//
ae_int_t n = 4;
ae_int_t bandwidth = 1;
sparsematrix s;
sparsecreatesksband(n, n, bandwidth, s);
sparseset(s, 0, 0, 2.0);
sparseset(s, 0, 1, 1.0);
sparseset(s, 1, 1, 3.0);
sparseset(s, 1, 2, 1.0);
sparseset(s, 2, 2, 3.0);
sparseset(s, 2, 3, 1.0);
sparseset(s, 3, 3, 2.0);
//
// Now we have symmetric positive definite 4x4 system width bandwidth=1:
//
// [ 2 1 ] [ x0]] [ 4 ]
// [ 1 3 1 ] [ x1 ] [ 10 ]
// [ 1 3 1 ] * [ x2 ] = [ 15 ]
// [ 1 2 ] [ x3 ] [ 11 ]
//
// After successful creation we can call SKS solver.
//
real_1d_array b = "[4,10,15,11]";
sparsesolverreport rep;
real_1d_array x;
bool isuppertriangle = true;
sparsespdsolvesks(s, isuppertriangle, b, x, rep);
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [1.0000, 2.0000, 3.0000, 4.0000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates creation/initialization of a sparse matrix and linear
// system solution using a direct solver. This solver can handle any problem sizes
// - from several tens of variables to millions of variables.
//
// First, we create a sparse matrix in the flexible hash table-based storage format,
// initialize it and convert to the CRS format.
//
ae_int_t n = 4;
sparsematrix s;
sparsecreate(n, n, 0, s);
sparseset(s, 0, 0, 2.0);
sparseset(s, 0, 1, 1.0);
sparseset(s, 1, 0, 1.0);
sparseset(s, 1, 1, 3.0);
sparseset(s, 1, 2, -1.0);
sparseset(s, 2, 2, 3.0);
sparseset(s, 2, 3, 1.0);
sparseset(s, 3, 2, 1.0);
sparseset(s, 3, 3, 2.0);
//
// Now we have symmetric positive definite 4x4 system
//
// [ 2 1 ] [ x0]] [ 3 ]
// [ 1 3 -1 ] [ x1 ] [ 2 ]
// [ 3 1 ] * [ x2 ] = [ 8 ]
// [ 1 2 ] [ x3 ] [ 6 ]
//
// Now, it is time to call the solver. The sparsesolve() function supports several
// solvers, our recommendation is to choose the default one. In the current version
// it is a supernodal solver with static pivoting, followed by the iterative refinement.
//
real_1d_array b = "[3,2,8,6]";
sparsesolverreport rep;
real_1d_array x;
ae_int_t solvertype = 0;
sparsesolve(s, b, solvertype, x, rep);
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [1.0000, 1.0000, 2.0000, 2.0000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates creation/initialization of a sparse matrix and linear
// system solution using Cholesky-based direct solver. This solver can handle any
// problem sizes - from several tens of variables to millions of variables.
//
// First, we create a sparse matrix in the flexible hash table-based storage format,
// initialize it and convert to the CRS format. Because the matrix is symmetric,
// it is enough to specify only one triangle. The example below initializes the
// lower one.
//
ae_int_t n = 4;
sparsematrix s;
sparsecreate(n, n, 0, s);
sparseset(s, 0, 0, 2.0);
sparseset(s, 1, 0, 1.0);
sparseset(s, 1, 1, 3.0);
sparseset(s, 2, 1, 1.0);
sparseset(s, 2, 2, 3.0);
sparseset(s, 3, 2, 1.0);
sparseset(s, 3, 3, 2.0);
//
// Now we have symmetric positive definite 4x4 system
//
// [ 2 1 ] [ x0]] [ 4 ]
// [ 1 3 1 ] [ x1 ] [ 10 ]
// [ 1 3 1 ] * [ x2 ] = [ 15 ]
// [ 1 2 ] [ x3 ] [ 11 ]
//
// Now, it is time to call the solver.
//
real_1d_array b = "[4,10,15,11]";
sparsesolverreport rep;
real_1d_array x;
bool isuppertriangle = false;
sparsespdsolve(s, isuppertriangle, b, x, rep);
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [1.0000, 2.0000, 3.0000, 4.0000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
elliptic subpackageellipticintegrale function/************************************************************************* Complete elliptic integral of the second kind Approximates the integral pi/2 - | | 2 E(m) = | sqrt( 1 - m sin t ) dt | | - 0 using the approximation P(x) - x log x Q(x). ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0, 1 10000 2.1e-16 7.3e-17 Cephes Math Library, Release 2.8: June, 2000 Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier *************************************************************************/double ellipticintegrale(const double m, const xparams _xparams = alglib::xdefault);
ellipticintegralk function/************************************************************************* Complete elliptic integral of the first kind Approximates the integral pi/2 - | | | dt K(m) = | ------------------ | 2 | | sqrt( 1 - m sin t ) - 0 using the approximation P(x) - log x Q(x). ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0,1 30000 2.5e-16 6.8e-17 Cephes Math Library, Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double ellipticintegralk(const double m, const xparams _xparams = alglib::xdefault);
ellipticintegralkhighprecision function/************************************************************************* Complete elliptic integral of the first kind Approximates the integral pi/2 - | | | dt K(m) = | ------------------ | 2 | | sqrt( 1 - m sin t ) - 0 where m = 1 - m1, using the approximation P(x) - log x Q(x). The argument m1 is used rather than m so that the logarithmic singularity at m = 1 will be shifted to the origin; this preserves maximum accuracy. K(0) = pi/2. ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0,1 30000 2.5e-16 6.8e-17 Cephes Math Library, Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double ellipticintegralkhighprecision(const double m1, const xparams _xparams = alglib::xdefault);
incompleteellipticintegrale function/************************************************************************* Incomplete elliptic integral of the second kind Approximates the integral phi - | | | 2 E(phi_\m) = | sqrt( 1 - m sin t ) dt | | | - 0 of amplitude phi and modulus m, using the arithmetic - geometric mean algorithm. ACCURACY: Tested at random arguments with phi in [-10, 10] and m in [0, 1]. Relative error: arithmetic domain # trials peak rms IEEE -10,10 150000 3.3e-15 1.4e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1993, 2000 by Stephen L. Moshier *************************************************************************/double incompleteellipticintegrale(const double phi, const double m, const xparams _xparams = alglib::xdefault);
incompleteellipticintegralk function/************************************************************************* Incomplete elliptic integral of the first kind F(phi|m) Approximates the integral phi - | | | dt F(phi_\m) = | ------------------ | 2 | | sqrt( 1 - m sin t ) - 0 of amplitude phi and modulus m, using the arithmetic - geometric mean algorithm. ACCURACY: Tested at random points with m in [0, 1] and phi as indicated. Relative error: arithmetic domain # trials peak rms IEEE -10,10 200000 7.4e-16 1.0e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/double incompleteellipticintegralk(const double phi, const double m, const xparams _xparams = alglib::xdefault);
evd subpackageeigsubspacereport class/************************************************************************* This object stores state of the subspace iteration algorithm. You should use ALGLIB functions to work with this object. *************************************************************************/class eigsubspacereport { public: eigsubspacereport(); eigsubspacereport(const eigsubspacereport &rhs); eigsubspacereport& operator=(const eigsubspacereport &rhs); virtual ~eigsubspacereport(); ae_int_t iterationscount; };
eigsubspacestate class/************************************************************************* This object stores state of the subspace iteration algorithm. You should use ALGLIB functions to work with this object. *************************************************************************/class eigsubspacestate { public: eigsubspacestate(); eigsubspacestate(const eigsubspacestate &rhs); eigsubspacestate& operator=(const eigsubspacestate &rhs); virtual ~eigsubspacestate(); };
eigsubspacecreate function/************************************************************************* This function initializes subspace iteration solver. This solver is used to solve symmetric real eigenproblems where just a few (top K) eigenvalues and corresponding eigenvectors is required. This solver can be significantly faster than complete EVD decomposition in the following case: * when only just a small fraction of top eigenpairs of dense matrix is required. When K approaches N, this solver is slower than complete dense EVD * when problem matrix is sparse (and/or is not known explicitly, i.e. only matrix-matrix product can be performed) USAGE (explicit dense/sparse matrix): 1. User initializes algorithm state with eigsubspacecreate() call 2. [optional] User tunes solver parameters by calling eigsubspacesetcond() or other functions 3. User calls eigsubspacesolvedense() or eigsubspacesolvesparse() methods, which take algorithm state and 2D array or alglib.sparsematrix object. USAGE (out-of-core mode): 1. User initializes algorithm state with eigsubspacecreate() call 2. [optional] User tunes solver parameters by calling eigsubspacesetcond() or other functions 3. User activates out-of-core mode of the solver and repeatedly calls communication functions in a loop like below: > alglib.eigsubspaceoocstart(state) > while alglib.eigsubspaceooccontinue(state) do > alglib.eigsubspaceoocgetrequestinfo(state, out RequestType, out M) > alglib.eigsubspaceoocgetrequestdata(state, out X) > [calculate Y=A*X, with X=R^NxM] > alglib.eigsubspaceoocsendresult(state, in Y) > alglib.eigsubspaceoocstop(state, out W, out Z, out Report) INPUT PARAMETERS: N - problem dimensionality, N>0 K - number of top eigenvector to calculate, 0<K<=N. OUTPUT PARAMETERS: State - structure which stores algorithm state NOTE: if you solve many similar EVD problems you may find it useful to reuse previous subspace as warm-start point for new EVD problem. It can be done with eigsubspacesetwarmstart() function. -- ALGLIB -- Copyright 16.01.2017 by Bochkanov Sergey *************************************************************************/void eigsubspacecreate(const ae_int_t n, const ae_int_t k, eigsubspacestate &state, const xparams _xparams = alglib::xdefault);
eigsubspacecreatebuf function/************************************************************************* Buffered version of constructor which aims to reuse previously allocated memory as much as possible. -- ALGLIB -- Copyright 16.01.2017 by Bochkanov Sergey *************************************************************************/void eigsubspacecreatebuf(const ae_int_t n, const ae_int_t k, eigsubspacestate &state, const xparams _xparams = alglib::xdefault);
eigsubspaceooccontinue function/************************************************************************* This function performs subspace iteration in the out-of-core mode. It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like below: > alglib.eigsubspaceoocstart(state) > while alglib.eigsubspaceooccontinue(state) do > alglib.eigsubspaceoocgetrequestinfo(state, out RequestType, out M) > alglib.eigsubspaceoocgetrequestdata(state, out X) > [calculate Y=A*X, with X=R^NxM] > alglib.eigsubspaceoocsendresult(state, in Y) > alglib.eigsubspaceoocstop(state, out W, out Z, out Report) -- ALGLIB -- Copyright 16.01.2017 by Bochkanov Sergey *************************************************************************/bool eigsubspaceooccontinue(eigsubspacestate &state, const xparams _xparams = alglib::xdefault);
eigsubspaceoocgetrequestdata function/************************************************************************* This function is used to retrieve information about out-of-core request sent by solver to user code: matrix X (array[N,RequestSize) which have to be multiplied by out-of-core matrix A in a product A*X. This function returns just request data; in order to get size of the data prior to processing requestm, use eigsubspaceoocgetrequestinfo(). It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like below: > alglib.eigsubspaceoocstart(state) > while alglib.eigsubspaceooccontinue(state) do > alglib.eigsubspaceoocgetrequestinfo(state, out RequestType, out M) > alglib.eigsubspaceoocgetrequestdata(state, out X) > [calculate Y=A*X, with X=R^NxM] > alglib.eigsubspaceoocsendresult(state, in Y) > alglib.eigsubspaceoocstop(state, out W, out Z, out Report) INPUT PARAMETERS: State - solver running in out-of-core mode X - possibly preallocated storage; reallocated if needed, left unchanged, if large enough to store request data. OUTPUT PARAMETERS: X - array[N,RequestSize] or larger, leading rectangle is filled with dense matrix X. -- ALGLIB -- Copyright 16.01.2017 by Bochkanov Sergey *************************************************************************/void eigsubspaceoocgetrequestdata(eigsubspacestate &state, real_2d_array &x, const xparams _xparams = alglib::xdefault);
eigsubspaceoocgetrequestinfo function/************************************************************************* This function is used to retrieve information about out-of-core request sent by solver to user code: request type (current version of the solver sends only requests for matrix-matrix products) and request size (size of the matrices being multiplied). This function returns just request metrics; in order to get contents of the matrices being multiplied, use eigsubspaceoocgetrequestdata(). It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like below: > alglib.eigsubspaceoocstart(state) > while alglib.eigsubspaceooccontinue(state) do > alglib.eigsubspaceoocgetrequestinfo(state, out RequestType, out M) > alglib.eigsubspaceoocgetrequestdata(state, out X) > [calculate Y=A*X, with X=R^NxM] > alglib.eigsubspaceoocsendresult(state, in Y) > alglib.eigsubspaceoocstop(state, out W, out Z, out Report) INPUT PARAMETERS: State - solver running in out-of-core mode OUTPUT PARAMETERS: RequestType - type of the request to process: * 0 - for matrix-matrix product A*X, with A being NxN matrix whose eigenvalues/vectors are needed, and X being NxREQUESTSIZE one which is returned by the eigsubspaceoocgetrequestdata(). RequestSize - size of the X matrix (number of columns), usually it is several times larger than number of vectors K requested by user. -- ALGLIB -- Copyright 16.01.2017 by Bochkanov Sergey *************************************************************************/void eigsubspaceoocgetrequestinfo(eigsubspacestate &state, ae_int_t &requesttype, ae_int_t &requestsize, const xparams _xparams = alglib::xdefault);
eigsubspaceoocsendresult function/************************************************************************* This function is used to send user reply to out-of-core request sent by solver. Usually it is product A*X for returned by solver matrix X. It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like below: > alglib.eigsubspaceoocstart(state) > while alglib.eigsubspaceooccontinue(state) do > alglib.eigsubspaceoocgetrequestinfo(state, out RequestType, out M) > alglib.eigsubspaceoocgetrequestdata(state, out X) > [calculate Y=A*X, with X=R^NxM] > alglib.eigsubspaceoocsendresult(state, in Y) > alglib.eigsubspaceoocstop(state, out W, out Z, out Report) INPUT PARAMETERS: State - solver running in out-of-core mode AX - array[N,RequestSize] or larger, leading rectangle is filled with product A*X. -- ALGLIB -- Copyright 16.01.2017 by Bochkanov Sergey *************************************************************************/void eigsubspaceoocsendresult(eigsubspacestate &state, const real_2d_array &ax, const xparams _xparams = alglib::xdefault);
eigsubspaceoocstart function/************************************************************************* This function initiates out-of-core mode of subspace eigensolver. It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like below: > alglib.eigsubspaceoocstart(state) > while alglib.eigsubspaceooccontinue(state) do > alglib.eigsubspaceoocgetrequestinfo(state, out RequestType, out M) > alglib.eigsubspaceoocgetrequestdata(state, out X) > [calculate Y=A*X, with X=R^NxM] > alglib.eigsubspaceoocsendresult(state, in Y) > alglib.eigsubspaceoocstop(state, out W, out Z, out Report) INPUT PARAMETERS: State - solver object MType - matrix type and solver mode: * 0 = real symmetric matrix A, products of the form A*X are computed. At every step the basis of the invariant subspace is reorthogonalized with LQ decomposition which makes the algo more robust. The first mode introduced in ALGLIB, the most precise and robust. However, it is suboptimal for easy problems which can be solved in 3-5 iterations without LQ step. * 1 = real symmetric matrix A, products of the form A*X are computed. The invariant subspace is NOT reorthogonalized, no error checks. The solver stops after specified number of iterations which should be small, 5 at most. This mode is intended for easy problems with extremely fast convergence. Future versions of ALGLIB may introduce support for other matrix types; for now, only symmetric eigenproblems are supported. -- ALGLIB -- Copyright 07.06.2023 by Bochkanov Sergey *************************************************************************/void eigsubspaceoocstart(eigsubspacestate &state, const ae_int_t mtype, const xparams _xparams = alglib::xdefault);
eigsubspaceoocstop function/************************************************************************* This function finalizes out-of-core mode of subspace eigensolver. It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like below: > alglib.eigsubspaceoocstart(state) > while alglib.eigsubspaceooccontinue(state) do > alglib.eigsubspaceoocgetrequestinfo(state, out RequestType, out M) > alglib.eigsubspaceoocgetrequestdata(state, out X) > [calculate Y=A*X, with X=R^NxM] > alglib.eigsubspaceoocsendresult(state, in Y) > alglib.eigsubspaceoocstop(state, out W, out Z, out Report) INPUT PARAMETERS: State - solver state OUTPUT PARAMETERS: W - array[K], depending on solver settings: * top K eigenvalues ordered by descending - if eigenvectors are returned in Z * zeros - if invariant subspace is returned in Z Z - array[N,K], depending on solver settings either: * matrix of eigenvectors found * orthogonal basis of K-dimensional invariant subspace Rep - report with additional parameters -- ALGLIB -- Copyright 16.01.2017 by Bochkanov Sergey *************************************************************************/void eigsubspaceoocstop(eigsubspacestate &state, real_1d_array &w, real_2d_array &z, eigsubspacereport &rep, const xparams _xparams = alglib::xdefault);
eigsubspacesetcond function/************************************************************************* This function sets stopping critera for the solver: * error in eigenvector/value allowed by solver * maximum number of iterations to perform INPUT PARAMETERS: State - solver structure Eps - eps>=0, with non-zero value used to tell solver that it can stop after all eigenvalues converged with error roughly proportional to eps*MAX(LAMBDA_MAX), where LAMBDA_MAX is a maximum eigenvalue. Zero value means that no check for precision is performed. MaxIts - maxits>=0, with non-zero value used to tell solver that it can stop after maxits steps (no matter how precise current estimate is) NOTE: passing eps=0 and maxits=0 results in automatic selection of moderate eps as stopping criteria (1.0E-6 in current implementation, but it may change without notice). NOTE: very small values of eps are possible (say, 1.0E-12), although the larger problem you solve (N and/or K), the harder it is to find precise eigenvectors because rounding errors tend to accumulate. NOTE: passing non-zero eps results in some performance penalty, roughly equal to 2N*(2K)^2 FLOPs per iteration. These additional computations are required in order to estimate current error in eigenvalues via Rayleigh-Ritz process. Most of this additional time is spent in construction of ~2Kx2K symmetric subproblem whose eigenvalues are checked with exact eigensolver. This additional time is negligible if you search for eigenvalues of the large dense matrix, but may become noticeable on highly sparse EVD problems, where cost of matrix-matrix product is low. If you set eps to exactly zero, Rayleigh-Ritz phase is completely turned off. -- ALGLIB -- Copyright 16.01.2017 by Bochkanov Sergey *************************************************************************/void eigsubspacesetcond(eigsubspacestate &state, const double eps, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
eigsubspacesetwarmstart function/************************************************************************* This function sets warm-start mode of the solver: next call to the solver will reuse previous subspace as warm-start point. It can significantly speed-up convergence when you solve many similar eigenproblems. INPUT PARAMETERS: State - solver structure UseWarmStart- either True or False -- ALGLIB -- Copyright 12.11.2017 by Bochkanov Sergey *************************************************************************/void eigsubspacesetwarmstart(eigsubspacestate &state, const bool usewarmstart, const xparams _xparams = alglib::xdefault);
eigsubspacesolvedenses function/************************************************************************* This function runs subspace eigensolver for dense NxN symmetric matrix A, given by its upper or lower triangle. This function can not process nonsymmetric matrices. INPUT PARAMETERS: State - solver state A - array[N,N], symmetric NxN matrix given by one of its triangles IsUpper - whether upper or lower triangle of A is given (the other one is not referenced at all). OUTPUT PARAMETERS: W - array[K], top K eigenvalues ordered by descending of their absolute values Z - array[N,K], matrix of eigenvectors found Rep - report with additional parameters NOTE: internally this function allocates a copy of NxN dense A. You should take it into account when working with very large matrices occupying almost all RAM. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 16.01.2017 by Bochkanov Sergey *************************************************************************/void eigsubspacesolvedenses(eigsubspacestate &state, const real_2d_array &a, const bool isupper, real_1d_array &w, real_2d_array &z, eigsubspacereport &rep, const xparams _xparams = alglib::xdefault);
eigsubspacesolvesparses function/************************************************************************* This function runs eigensolver for dense NxN symmetric matrix A, given by upper or lower triangle. This function can not process nonsymmetric matrices. INPUT PARAMETERS: State - solver state A - NxN symmetric matrix given by one of its triangles IsUpper - whether upper or lower triangle of A is given (the other one is not referenced at all). OUTPUT PARAMETERS: W - array[K], top K eigenvalues ordered by descending of their absolute values Z - array[N,K], matrix of eigenvectors found Rep - report with additional parameters -- ALGLIB -- Copyright 16.01.2017 by Bochkanov Sergey *************************************************************************/void eigsubspacesolvesparses(eigsubspacestate &state, const sparsematrix &a, const bool isupper, real_1d_array &w, real_2d_array &z, eigsubspacereport &rep, const xparams _xparams = alglib::xdefault);
hmatrixevd function/************************************************************************* Finding the eigenvalues and eigenvectors of a Hermitian matrix The algorithm finds eigen pairs of a Hermitian matrix by reducing it to real tridiagonal form and using the QL/QR algorithm. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions, x64/ARM platform) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. Input parameters: A - Hermitian matrix which is given by its upper or lower triangular part. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. IsUpper - storage format. ZNeeded - flag controlling whether the eigenvectors are needed or not. If ZNeeded is equal to: * 0, the eigenvectors are not returned; * 1, the eigenvectors are returned. Output parameters: D - eigenvalues in ascending order. Array whose index ranges within [0..N-1]. Z - if ZNeeded is equal to: * 0, Z hasn't changed; * 1, Z contains the eigenvectors. Array whose indexes range within [0..N-1, 0..N-1]. The eigenvectors are stored in the matrix columns. Result: True, if the algorithm has converged. False, if the algorithm hasn't converged (rare case). Note: eigenvectors of Hermitian matrix are defined up to multiplication by a complex number L, such that |L|=1. -- ALGLIB -- Copyright 2005, 23 March 2007 by Bochkanov Sergey *************************************************************************/bool hmatrixevd(const complex_2d_array &a, const ae_int_t n, const ae_int_t zneeded, const bool isupper, real_1d_array &d, complex_2d_array &z, const xparams _xparams = alglib::xdefault);
hmatrixevdi function/************************************************************************* Subroutine for finding the eigenvalues and eigenvectors of a Hermitian matrix with given indexes by using bisection and inverse iteration methods Input parameters: A - Hermitian matrix which is given by its upper or lower triangular part. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. ZNeeded - flag controlling whether the eigenvectors are needed or not. If ZNeeded is equal to: * 0, the eigenvectors are not returned; * 1, the eigenvectors are returned. IsUpperA - storage format of matrix A. I1, I2 - index interval for searching (from I1 to I2). 0 <= I1 <= I2 <= N-1. Output parameters: W - array of the eigenvalues found. Array whose index ranges within [0..I2-I1]. Z - if ZNeeded is equal to: * 0, Z hasn't changed; * 1, Z contains eigenvectors. Array whose indexes range within [0..N-1, 0..I2-I1]. In that case, the eigenvectors are stored in the matrix columns. Result: True, if successful. W contains the eigenvalues, Z contains the eigenvectors (if needed). False, if the bisection method subroutine wasn't able to find the eigenvalues in the given interval or if the inverse iteration subroutine wasn't able to find all the corresponding eigenvectors. In that case, the eigenvalues and eigenvectors are not returned. Note: eigen vectors of Hermitian matrix are defined up to multiplication by a complex number L, such as |L|=1. -- ALGLIB -- Copyright 07.01.2006, 24.03.2007 by Bochkanov Sergey. *************************************************************************/bool hmatrixevdi(const complex_2d_array &a, const ae_int_t n, const ae_int_t zneeded, const bool isupper, const ae_int_t i1, const ae_int_t i2, real_1d_array &w, complex_2d_array &z, const xparams _xparams = alglib::xdefault);
hmatrixevdr function/************************************************************************* Subroutine for finding the eigenvalues (and eigenvectors) of a Hermitian matrix in a given half-interval (A, B] by using a bisection and inverse iteration Input parameters: A - Hermitian matrix which is given by its upper or lower triangular part. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. ZNeeded - flag controlling whether the eigenvectors are needed or not. If ZNeeded is equal to: * 0, the eigenvectors are not returned; * 1, the eigenvectors are returned. IsUpperA - storage format of matrix A. B1, B2 - half-interval (B1, B2] to search eigenvalues in. Output parameters: M - number of eigenvalues found in a given half-interval, M>=0 W - array of the eigenvalues found. Array whose index ranges within [0..M-1]. Z - if ZNeeded is equal to: * 0, Z hasn't changed; * 1, Z contains eigenvectors. Array whose indexes range within [0..N-1, 0..M-1]. The eigenvectors are stored in the matrix columns. Result: True, if successful. M contains the number of eigenvalues in the given half-interval (could be equal to 0), W contains the eigenvalues, Z contains the eigenvectors (if needed). False, if the bisection method subroutine wasn't able to find the eigenvalues in the given interval or if the inverse iteration subroutine wasn't able to find all the corresponding eigenvectors. In that case, the eigenvalues and eigenvectors are not returned, M is equal to 0. Note: eigen vectors of Hermitian matrix are defined up to multiplication by a complex number L, such as |L|=1. -- ALGLIB -- Copyright 07.01.2006, 24.03.2007 by Bochkanov Sergey. *************************************************************************/bool hmatrixevdr(const complex_2d_array &a, const ae_int_t n, const ae_int_t zneeded, const bool isupper, const double b1, const double b2, ae_int_t &m, real_1d_array &w, complex_2d_array &z, const xparams _xparams = alglib::xdefault);
rmatrixevd function/************************************************************************* Finding eigenvalues and eigenvectors of a general (unsymmetric) matrix ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions, x64/ARM platform) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. The algorithm finds eigenvalues and eigenvectors of a general matrix by using the QR algorithm with multiple shifts. The algorithm can find eigenvalues and both left and right eigenvectors. The right eigenvector is a vector x such that A*x = w*x, and the left eigenvector is a vector y such that y'*A = w*y' (here y' implies a complex conjugate transposition of vector y). Input parameters: A - matrix. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. VNeeded - flag controlling whether eigenvectors are needed or not. If VNeeded is equal to: * 0, eigenvectors are not returned; * 1, right eigenvectors are returned; * 2, left eigenvectors are returned; * 3, both left and right eigenvectors are returned. Output parameters: WR - real parts of eigenvalues. Array whose index ranges within [0..N-1]. WR - imaginary parts of eigenvalues. Array whose index ranges within [0..N-1]. VL, VR - arrays of left and right eigenvectors (if they are needed). If WI[i]=0, the respective eigenvalue is a real number, and it corresponds to the column number I of matrices VL/VR. If WI[i]>0, we have a pair of complex conjugate numbers with positive and negative imaginary parts: the first eigenvalue WR[i] + sqrt(-1)*WI[i]; the second eigenvalue WR[i+1] + sqrt(-1)*WI[i+1]; WI[i]>0 WI[i+1] = -WI[i] < 0 In that case, the eigenvector corresponding to the first eigenvalue is located in i and i+1 columns of matrices VL/VR (the column number i contains the real part, and the column number i+1 contains the imaginary part), and the vector corresponding to the second eigenvalue is a complex conjugate to the first vector. Arrays whose indexes range within [0..N-1, 0..N-1]. Result: True, if the algorithm has converged. False, if the algorithm has not converged. Note 1: Some users may ask the following question: what if WI[N-1]>0? WI[N] must contain an eigenvalue which is complex conjugate to the N-th eigenvalue, but the array has only size N? The answer is as follows: such a situation cannot occur because the algorithm finds a pairs of eigenvalues, therefore, if WI[i]>0, I is strictly less than N-1. Note 2: The algorithm performance depends on the value of the internal parameter NS of the InternalSchurDecomposition subroutine which defines the number of shifts in the QR algorithm (similarly to the block width in block-matrix algorithms of linear algebra). If you require maximum performance on your machine, it is recommended to adjust this parameter manually. See also the InternalTREVC subroutine. The algorithm is based on the LAPACK 3.0 library. *************************************************************************/bool rmatrixevd(const real_2d_array &a, const ae_int_t n, const ae_int_t vneeded, real_1d_array &wr, real_1d_array &wi, real_2d_array &vl, real_2d_array &vr, const xparams _xparams = alglib::xdefault);
smatrixevd function/************************************************************************* Finding the eigenvalues and eigenvectors of a symmetric matrix The algorithm finds eigen pairs of a symmetric matrix by reducing it to tridiagonal form and using the QL/QR algorithm. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions, x64/ARM platform) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. Input parameters: A - symmetric matrix which is given by its upper or lower triangular part. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. ZNeeded - flag controlling whether the eigenvectors are needed or not. If ZNeeded is equal to: * 0, the eigenvectors are not returned; * 1, the eigenvectors are returned. IsUpper - storage format. Output parameters: D - eigenvalues in ascending order. Array whose index ranges within [0..N-1]. Z - if ZNeeded is equal to: * 0, Z hasn't changed; * 1, Z contains the eigenvectors. Array whose indexes range within [0..N-1, 0..N-1]. The eigenvectors are stored in the matrix columns. Result: True, if the algorithm has converged. False, if the algorithm hasn't converged (rare case). -- ALGLIB -- Copyright 2005-2008 by Bochkanov Sergey *************************************************************************/bool smatrixevd(const real_2d_array &a, const ae_int_t n, const ae_int_t zneeded, const bool isupper, real_1d_array &d, real_2d_array &z, const xparams _xparams = alglib::xdefault);
smatrixevdi function/************************************************************************* Subroutine for finding the eigenvalues and eigenvectors of a symmetric matrix with given indexes by using bisection and inverse iteration methods. Input parameters: A - symmetric matrix which is given by its upper or lower triangular part. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. ZNeeded - flag controlling whether the eigenvectors are needed or not. If ZNeeded is equal to: * 0, the eigenvectors are not returned; * 1, the eigenvectors are returned. IsUpperA - storage format of matrix A. I1, I2 - index interval for searching (from I1 to I2). 0 <= I1 <= I2 <= N-1. Output parameters: W - array of the eigenvalues found. Array whose index ranges within [0..I2-I1]. Z - if ZNeeded is equal to: * 0, Z hasn't changed; * 1, Z contains eigenvectors. Array whose indexes range within [0..N-1, 0..I2-I1]. In that case, the eigenvectors are stored in the matrix columns. Result: True, if successful. W contains the eigenvalues, Z contains the eigenvectors (if needed). False, if the bisection method subroutine wasn't able to find the eigenvalues in the given interval or if the inverse iteration subroutine wasn't able to find all the corresponding eigenvectors. In that case, the eigenvalues and eigenvectors are not returned. -- ALGLIB -- Copyright 07.01.2006 by Bochkanov Sergey *************************************************************************/bool smatrixevdi(const real_2d_array &a, const ae_int_t n, const ae_int_t zneeded, const bool isupper, const ae_int_t i1, const ae_int_t i2, real_1d_array &w, real_2d_array &z, const xparams _xparams = alglib::xdefault);
smatrixevdr function/************************************************************************* Subroutine for finding the eigenvalues (and eigenvectors) of a symmetric matrix in a given half open interval (A, B] by using a bisection and inverse iteration ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions, x64/ARM platform) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. Input parameters: A - symmetric matrix which is given by its upper or lower triangular part. Array [0..N-1, 0..N-1]. N - size of matrix A. ZNeeded - flag controlling whether the eigenvectors are needed or not. If ZNeeded is equal to: * 0, the eigenvectors are not returned; * 1, the eigenvectors are returned. IsUpperA - storage format of matrix A. B1, B2 - half open interval (B1, B2] to search eigenvalues in. Output parameters: M - number of eigenvalues found in a given half-interval (M>=0). W - array of the eigenvalues found. Array whose index ranges within [0..M-1]. Z - if ZNeeded is equal to: * 0, Z hasn't changed; * 1, Z contains eigenvectors. Array whose indexes range within [0..N-1, 0..M-1]. The eigenvectors are stored in the matrix columns. Result: True, if successful. M contains the number of eigenvalues in the given half-interval (could be equal to 0), W contains the eigenvalues, Z contains the eigenvectors (if needed). False, if the bisection method subroutine wasn't able to find the eigenvalues in the given interval or if the inverse iteration subroutine wasn't able to find all the corresponding eigenvectors. In that case, the eigenvalues and eigenvectors are not returned, M is equal to 0. -- ALGLIB -- Copyright 07.01.2006 by Bochkanov Sergey *************************************************************************/bool smatrixevdr(const real_2d_array &a, const ae_int_t n, const ae_int_t zneeded, const bool isupper, const double b1, const double b2, ae_int_t &m, real_1d_array &w, real_2d_array &z, const xparams _xparams = alglib::xdefault);
smatrixtdevd function/************************************************************************* Finding the eigenvalues and eigenvectors of a tridiagonal symmetric matrix The algorithm finds the eigen pairs of a tridiagonal symmetric matrix by using an QL/QR algorithm with implicit shifts. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions, x64/ARM platform) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. Input parameters: D - the main diagonal of a tridiagonal matrix. Array whose index ranges within [0..N-1]. E - the secondary diagonal of a tridiagonal matrix. Array whose index ranges within [0..N-2]. N - size of matrix A. ZNeeded - flag controlling whether the eigenvectors are needed or not. If ZNeeded is equal to: * 0, the eigenvectors are not needed; * 1, the eigenvectors of a tridiagonal matrix are multiplied by the square matrix Z. It is used if the tridiagonal matrix is obtained by the similarity transformation of a symmetric matrix; * 2, the eigenvectors of a tridiagonal matrix replace the square matrix Z; * 3, matrix Z contains the first row of the eigenvectors matrix. Z - if ZNeeded=1, Z contains the square matrix by which the eigenvectors are multiplied. Array whose indexes range within [0..N-1, 0..N-1]. Output parameters: D - eigenvalues in ascending order. Array whose index ranges within [0..N-1]. Z - if ZNeeded is equal to: * 0, Z hasn't changed; * 1, Z contains the product of a given matrix (from the left) and the eigenvectors matrix (from the right); * 2, Z contains the eigenvectors. * 3, Z contains the first row of the eigenvectors matrix. If ZNeeded<3, Z is the array whose indexes range within [0..N-1, 0..N-1]. In that case, the eigenvectors are stored in the matrix columns. If ZNeeded=3, Z is the array whose indexes range within [0..0, 0..N-1]. Result: True, if the algorithm has converged. False, if the algorithm hasn't converged. -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 *************************************************************************/bool smatrixtdevd(real_1d_array &d, const real_1d_array &e, const ae_int_t n, const ae_int_t zneeded, real_2d_array &z, const xparams _xparams = alglib::xdefault);
smatrixtdevdi function/************************************************************************* Subroutine for finding tridiagonal matrix eigenvalues/vectors with given indexes (in ascending order) by using the bisection and inverse iteraion. Input parameters: D - the main diagonal of a tridiagonal matrix. Array whose index ranges within [0..N-1]. E - the secondary diagonal of a tridiagonal matrix. Array whose index ranges within [0..N-2]. N - size of matrix. N>=0. ZNeeded - flag controlling whether the eigenvectors are needed or not. If ZNeeded is equal to: * 0, the eigenvectors are not needed; * 1, the eigenvectors of a tridiagonal matrix are multiplied by the square matrix Z. It is used if the tridiagonal matrix is obtained by the similarity transformation of a symmetric matrix. * 2, the eigenvectors of a tridiagonal matrix replace matrix Z. I1, I2 - index interval for searching (from I1 to I2). 0 <= I1 <= I2 <= N-1. Z - if ZNeeded is equal to: * 0, Z isn't used and remains unchanged; * 1, Z contains the square matrix (array whose indexes range within [0..N-1, 0..N-1]) which reduces the given symmetric matrix to tridiagonal form; * 2, Z isn't used (but changed on the exit). Output parameters: D - array of the eigenvalues found. Array whose index ranges within [0..I2-I1]. Z - if ZNeeded is equal to: * 0, doesn't contain any information; * 1, contains the product of a given NxN matrix Z (from the left) and Nx(I2-I1) matrix of the eigenvectors found (from the right). Array whose indexes range within [0..N-1, 0..I2-I1]. * 2, contains the matrix of the eigenvalues found. Array whose indexes range within [0..N-1, 0..I2-I1]. Result: True, if successful. In that case, D contains the eigenvalues, Z contains the eigenvectors (if needed). It should be noted that the subroutine changes the size of arrays D and Z. False, if the bisection method subroutine wasn't able to find the eigenvalues in the given interval or if the inverse iteration subroutine wasn't able to find all the corresponding eigenvectors. In that case, the eigenvalues and eigenvectors are not returned. -- ALGLIB -- Copyright 25.12.2005 by Bochkanov Sergey *************************************************************************/bool smatrixtdevdi(real_1d_array &d, const real_1d_array &e, const ae_int_t n, const ae_int_t zneeded, const ae_int_t i1, const ae_int_t i2, real_2d_array &z, const xparams _xparams = alglib::xdefault);
smatrixtdevdr function/************************************************************************* Subroutine for finding the tridiagonal matrix eigenvalues/vectors in a given half-interval (A, B] by using bisection and inverse iteration. Input parameters: D - the main diagonal of a tridiagonal matrix. Array whose index ranges within [0..N-1]. E - the secondary diagonal of a tridiagonal matrix. Array whose index ranges within [0..N-2]. N - size of matrix, N>=0. ZNeeded - flag controlling whether the eigenvectors are needed or not. If ZNeeded is equal to: * 0, the eigenvectors are not needed; * 1, the eigenvectors of a tridiagonal matrix are multiplied by the square matrix Z. It is used if the tridiagonal matrix is obtained by the similarity transformation of a symmetric matrix. * 2, the eigenvectors of a tridiagonal matrix replace matrix Z. A, B - half-interval (A, B] to search eigenvalues in. Z - if ZNeeded is equal to: * 0, Z isn't used and remains unchanged; * 1, Z contains the square matrix (array whose indexes range within [0..N-1, 0..N-1]) which reduces the given symmetric matrix to tridiagonal form; * 2, Z isn't used (but changed on the exit). Output parameters: D - array of the eigenvalues found. Array whose index ranges within [0..M-1]. M - number of eigenvalues found in the given half-interval (M>=0). Z - if ZNeeded is equal to: * 0, doesn't contain any information; * 1, contains the product of a given NxN matrix Z (from the left) and NxM matrix of the eigenvectors found (from the right). Array whose indexes range within [0..N-1, 0..M-1]. * 2, contains the matrix of the eigenvectors found. Array whose indexes range within [0..N-1, 0..M-1]. Result: True, if successful. In that case, M contains the number of eigenvalues in the given half-interval (could be equal to 0), D contains the eigenvalues, Z contains the eigenvectors (if needed). It should be noted that the subroutine changes the size of arrays D and Z. False, if the bisection method subroutine wasn't able to find the eigenvalues in the given interval or if the inverse iteration subroutine wasn't able to find all the corresponding eigenvectors. In that case, the eigenvalues and eigenvectors are not returned, M is equal to 0. -- ALGLIB -- Copyright 31.03.2008 by Bochkanov Sergey *************************************************************************/bool smatrixtdevdr(real_1d_array &d, const real_1d_array &e, const ae_int_t n, const ae_int_t zneeded, const double a, const double b, ae_int_t &m, real_2d_array &z, const xparams _xparams = alglib::xdefault);
expintegrals subpackageexponentialintegralei function/************************************************************************* Exponential integral Ei(x) x - t | | e Ei(x) = -|- --- dt . | | t - -inf Not defined for x <= 0. See also expn.c. ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0,100 50000 8.6e-16 1.3e-16 Cephes Math Library Release 2.8: May, 1999 Copyright 1999 by Stephen L. Moshier *************************************************************************/double exponentialintegralei(const double x, const xparams _xparams = alglib::xdefault);
exponentialintegralen function/************************************************************************* Exponential integral En(x) Evaluates the exponential integral inf. - | | -xt | e E (x) = | ---- dt. n | n | | t - 1 Both n and x must be nonnegative. The routine employs either a power series, a continued fraction, or an asymptotic formula depending on the relative values of n and x. ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0, 30 10000 1.7e-15 3.6e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1985, 2000 by Stephen L. Moshier *************************************************************************/double exponentialintegralen(const double x, const ae_int_t n, const xparams _xparams = alglib::xdefault);
fdistr subpackagefcdistribution function/************************************************************************* Complemented F distribution Returns the area from x to infinity under the F density function (also known as Snedcor's density or the variance ratio density). inf. - 1 | | a-1 b-1 1-P(x) = ------ | t (1-t) dt B(a,b) | | - x The incomplete beta integral is used, according to the formula P(x) = incbet( df2/2, df1/2, (df2/(df2 + df1*x) ). ACCURACY: Tested at random points (a,b,x) in the indicated intervals. x a,b Relative error: arithmetic domain domain # trials peak rms IEEE 0,1 1,100 100000 3.7e-14 5.9e-16 IEEE 1,5 1,100 100000 8.0e-15 1.6e-15 IEEE 0,1 1,10000 100000 1.8e-11 3.5e-13 IEEE 1,5 1,10000 100000 2.0e-11 3.0e-12 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier *************************************************************************/double fcdistribution(const ae_int_t a, const ae_int_t b, const double x, const xparams _xparams = alglib::xdefault);
fdistribution function/************************************************************************* F distribution Returns the area from zero to x under the F density function (also known as Snedcor's density or the variance ratio density). This is the density of x = (u1/df1)/(u2/df2), where u1 and u2 are random variables having Chi square distributions with df1 and df2 degrees of freedom, respectively. The incomplete beta integral is used, according to the formula P(x) = incbet( df1/2, df2/2, (df1*x/(df2 + df1*x) ). The arguments a and b are greater than zero, and x is nonnegative. ACCURACY: Tested at random points (a,b,x). x a,b Relative error: arithmetic domain domain # trials peak rms IEEE 0,1 0,100 100000 9.8e-15 1.7e-15 IEEE 1,5 0,100 100000 6.5e-15 3.5e-16 IEEE 0,1 1,10000 100000 2.2e-11 3.3e-12 IEEE 1,5 1,10000 100000 1.1e-11 1.7e-13 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier *************************************************************************/double fdistribution(const ae_int_t a, const ae_int_t b, const double x, const xparams _xparams = alglib::xdefault);
invfdistribution function/************************************************************************* Inverse of complemented F distribution Finds the F density argument x such that the integral from x to infinity of the F density is equal to the given probability p. This is accomplished using the inverse beta integral function and the relations z = incbi( df2/2, df1/2, p ) x = df2 (1-z) / (df1 z). Note: the following relations hold for the inverse of the uncomplemented F distribution: z = incbi( df1/2, df2/2, p ) x = df2 z / (df1 (1-z)). ACCURACY: Tested at random points (a,b,p). a,b Relative error: arithmetic domain # trials peak rms For p between .001 and 1: IEEE 1,100 100000 8.3e-15 4.7e-16 IEEE 1,10000 100000 2.1e-11 1.4e-13 For p between 10^-6 and 10^-3: IEEE 1,100 50000 1.3e-12 8.4e-15 IEEE 1,10000 50000 3.0e-12 4.8e-14 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier *************************************************************************/double invfdistribution(const ae_int_t a, const ae_int_t b, const double y, const xparams _xparams = alglib::xdefault);
fft subpackage| fft_complex_d1 | Complex FFT: simple example | |
| fft_complex_d2 | Complex FFT: advanced example | |
| fft_real_d1 | Real FFT: simple example | |
| fft_real_d2 | Real FFT: advanced example |
fftc1d function/************************************************************************* 1-dimensional complex FFT. Array size N may be arbitrary number (composite or prime). Composite N's are handled with cache-oblivious variation of a Cooley-Tukey algorithm. Small prime-factors are transformed using hard coded codelets (similar to FFTW codelets, but without low-level optimization), large prime-factors are handled with Bluestein's algorithm. Fastests transforms are for smooth N's (prime factors are 2, 3, 5 only), most fast for powers of 2. When N have prime factors larger than these, but orders of magnitude smaller than N, computations will be about 4 times slower than for nearby highly composite N's. When N itself is prime, speed will be 6 times lower. Algorithm has O(N*logN) complexity for any N (composite or prime). INPUT PARAMETERS A - array[0..N-1] - complex function to be transformed N - problem size OUTPUT PARAMETERS A - DFT of a input array, array[0..N-1] A_out[j] = SUM(A_in[k]*exp(-2*pi*sqrt(-1)*j*k/N), k = 0..N-1) -- ALGLIB -- Copyright 29.05.2009 by Bochkanov Sergey *************************************************************************/void fftc1d(complex_1d_array &a, const ae_int_t n, const xparams _xparams = alglib::xdefault); void fftc1d(complex_1d_array &a, const xparams _xparams = alglib::xdefault);
fftc1dinv function/************************************************************************* 1-dimensional complex inverse FFT. Array size N may be arbitrary number (composite or prime). Algorithm has O(N*logN) complexity for any N (composite or prime). See FFTC1D() description for more information about algorithm performance. INPUT PARAMETERS A - array[0..N-1] - complex array to be transformed N - problem size OUTPUT PARAMETERS A - inverse DFT of a input array, array[0..N-1] A_out[j] = SUM(A_in[k]/N*exp(+2*pi*sqrt(-1)*j*k/N), k = 0..N-1) -- ALGLIB -- Copyright 29.05.2009 by Bochkanov Sergey *************************************************************************/void fftc1dinv(complex_1d_array &a, const ae_int_t n, const xparams _xparams = alglib::xdefault); void fftc1dinv(complex_1d_array &a, const xparams _xparams = alglib::xdefault);
fftr1d function/************************************************************************* 1-dimensional real FFT. Algorithm has O(N*logN) complexity for any N (composite or prime). INPUT PARAMETERS A - array[0..N-1] - real function to be transformed N - problem size OUTPUT PARAMETERS F - DFT of a input array, array[0..N-1] F[j] = SUM(A[k]*exp(-2*pi*sqrt(-1)*j*k/N), k = 0..N-1) NOTE: there is a buffered version of this function, FFTR1DBuf(), which reuses memory previously allocated for A as much as possible. NOTE: F[] satisfies symmetry property F[k] = conj(F[N-k]), so just one half of array is usually needed. But for convinience subroutine returns full complex array (with frequencies above N/2), so its result may be used by other FFT-related subroutines. -- ALGLIB -- Copyright 01.06.2009 by Bochkanov Sergey *************************************************************************/void fftr1d(const real_1d_array &a, const ae_int_t n, complex_1d_array &f, const xparams _xparams = alglib::xdefault); void fftr1d(const real_1d_array &a, complex_1d_array &f, const xparams _xparams = alglib::xdefault);
fftr1dbuf function/************************************************************************* 1-dimensional real FFT, a buffered function which does not reallocate F[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 01.06.2009 by Bochkanov Sergey *************************************************************************/void fftr1dbuf(const real_1d_array &a, const ae_int_t n, complex_1d_array &f, const xparams _xparams = alglib::xdefault); void fftr1dbuf(const real_1d_array &a, complex_1d_array &f, const xparams _xparams = alglib::xdefault);
fftr1dinv function/************************************************************************* 1-dimensional real inverse FFT. Algorithm has O(N*logN) complexity for any N (composite or prime). INPUT PARAMETERS F - array[0..floor(N/2)] - frequencies from forward real FFT N - problem size OUTPUT PARAMETERS A - inverse DFT of a input array, array[0..N-1] NOTE: there is a buffered version of this function, FFTR1DInvBuf(), which reuses memory previously allocated for A as much as possible. NOTE: F[] should satisfy symmetry property F[k] = conj(F[N-k]), so just one half of frequencies array is needed - elements from 0 to floor(N/2). F[0] is ALWAYS real. If N is even F[floor(N/2)] is real too. If N is odd, then F[floor(N/2)] has no special properties. Relying on properties noted above, FFTR1DInv subroutine uses only elements from 0th to floor(N/2)-th. It ignores imaginary part of F[0], and in case N is even it ignores imaginary part of F[floor(N/2)] too. When you call this function using full arguments list - "FFTR1DInv(F,N,A)" - you can pass either either frequencies array with N elements or reduced array with roughly N/2 elements - subroutine will successfully transform both. If you call this function using reduced arguments list - "FFTR1DInv(F,A)" - you must pass FULL array with N elements (although higher N/2 are still not used) because array size is used to automatically determine FFT length -- ALGLIB -- Copyright 01.06.2009 by Bochkanov Sergey *************************************************************************/void fftr1dinv(const complex_1d_array &f, const ae_int_t n, real_1d_array &a, const xparams _xparams = alglib::xdefault); void fftr1dinv(const complex_1d_array &f, real_1d_array &a, const xparams _xparams = alglib::xdefault);
fftr1dinvbuf function/************************************************************************* 1-dimensional real inverse FFT, buffered version, which does not reallocate A[] if its length is enough to store the result (i.e. it reuses previously allocated memory as much as possible). -- ALGLIB -- Copyright 01.06.2009 by Bochkanov Sergey *************************************************************************/void fftr1dinvbuf(const complex_1d_array &f, const ae_int_t n, real_1d_array &a, const xparams _xparams = alglib::xdefault); void fftr1dinvbuf(const complex_1d_array &f, real_1d_array &a, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "fasttransforms.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// first we demonstrate forward FFT:
// [1i,1i,1i,1i] is converted to [4i, 0, 0, 0]
//
complex_1d_array z = "[1i,1i,1i,1i]";
fftc1d(z);
printf("%s\n", z.tostring(3).c_str()); // EXPECTED: [4i,0,0,0]
//
// now we convert [4i, 0, 0, 0] back to [1i,1i,1i,1i]
// with backward FFT
//
fftc1dinv(z);
printf("%s\n", z.tostring(3).c_str()); // EXPECTED: [1i,1i,1i,1i]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "fasttransforms.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// first we demonstrate forward FFT:
// [0,1,0,1i] is converted to [1+1i, -1-1i, -1-1i, 1+1i]
//
complex_1d_array z = "[0,1,0,1i]";
fftc1d(z);
printf("%s\n", z.tostring(3).c_str()); // EXPECTED: [1+1i, -1-1i, -1-1i, 1+1i]
//
// now we convert result back with backward FFT
//
fftc1dinv(z);
printf("%s\n", z.tostring(3).c_str()); // EXPECTED: [0,1,0,1i]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "fasttransforms.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// first we demonstrate forward FFT:
// [1,1,1,1] is converted to [4, 0, 0, 0]
//
real_1d_array x = "[1,1,1,1]";
complex_1d_array f;
real_1d_array x2;
fftr1d(x, f);
printf("%s\n", f.tostring(3).c_str()); // EXPECTED: [4,0,0,0]
//
// now we convert [4, 0, 0, 0] back to [1,1,1,1]
// with backward FFT
//
fftr1dinv(f, x2);
printf("%s\n", x2.tostring(3).c_str()); // EXPECTED: [1,1,1,1]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "fasttransforms.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// first we demonstrate forward FFT:
// [1,2,3,4] is converted to [10, -2+2i, -2, -2-2i]
//
// note that output array is self-adjoint:
// * f[0] = conj(f[0])
// * f[1] = conj(f[3])
// * f[2] = conj(f[2])
//
real_1d_array x = "[1,2,3,4]";
complex_1d_array f;
real_1d_array x2;
fftr1d(x, f);
printf("%s\n", f.tostring(3).c_str()); // EXPECTED: [10, -2+2i, -2, -2-2i]
//
// now we convert [10, -2+2i, -2, -2-2i] back to [1,2,3,4]
//
fftr1dinv(f, x2);
printf("%s\n", x2.tostring(3).c_str()); // EXPECTED: [1,2,3,4]
//
// remember that F is self-adjoint? It means that we can pass just half
// (slightly larger than half) of F to inverse real FFT and still get our result.
//
// I.e. instead [10, -2+2i, -2, -2-2i] we pass just [10, -2+2i, -2] and everything works!
//
// NOTE: in this case we should explicitly pass array length (which is 4) to ALGLIB;
// if not, it will automatically use array length to determine FFT size and
// will erroneously make half-length FFT.
//
f = "[10, -2+2i, -2]";
fftr1dinv(f, 4, x2);
printf("%s\n", x2.tostring(3).c_str()); // EXPECTED: [1,2,3,4]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
fht subpackagefhtr1d function/************************************************************************* 1-dimensional Fast Hartley Transform. Algorithm has O(N*logN) complexity for any N (composite or prime). INPUT PARAMETERS A - array[0..N-1] - real function to be transformed N - problem size OUTPUT PARAMETERS A - FHT of a input array, array[0..N-1], A_out[k] = sum(A_in[j]*(cos(2*pi*j*k/N)+sin(2*pi*j*k/N)), j=0..N-1) -- ALGLIB -- Copyright 04.06.2009 by Bochkanov Sergey *************************************************************************/void fhtr1d(real_1d_array &a, const ae_int_t n, const xparams _xparams = alglib::xdefault);
fhtr1dinv function/************************************************************************* 1-dimensional inverse FHT. Algorithm has O(N*logN) complexity for any N (composite or prime). INPUT PARAMETERS A - array[0..N-1] - complex array to be transformed N - problem size OUTPUT PARAMETERS A - inverse FHT of a input array, array[0..N-1] -- ALGLIB -- Copyright 29.05.2009 by Bochkanov Sergey *************************************************************************/void fhtr1dinv(real_1d_array &a, const ae_int_t n, const xparams _xparams = alglib::xdefault);
filters subpackage| filters_d_ema | EMA(alpha) filter | |
| filters_d_lrma | LRMA(k) filter | |
| filters_d_sma | SMA(k) filter |
filterema function/************************************************************************* Filters: exponential moving averages. This filter replaces array by results of EMA(alpha) filter. EMA(alpha) is defined as filter which replaces X[] by S[]: S[0] = X[0] S[t] = alpha*X[t] + (1-alpha)*S[t-1] INPUT PARAMETERS: X - array[N], array to process. It can be larger than N, in this case only first N points are processed. N - points count, N>=0 alpha - 0<alpha<=1, smoothing parameter. OUTPUT PARAMETERS: X - array, whose first N elements were processed with EMA(alpha) NOTE 1: this function uses efficient in-place algorithm which does not allocate temporary arrays. NOTE 2: this algorithm uses BOTH previous points and current one, i.e. new value of X[i] depends on BOTH previous point and X[i] itself. NOTE 3: technical analytis users quite often work with EMA coefficient expressed in DAYS instead of fractions. If you want to calculate EMA(N), where N is a number of days, you can use alpha=2/(N+1). -- ALGLIB -- Copyright 25.10.2011 by Bochkanov Sergey *************************************************************************/void filterema(real_1d_array &x, const ae_int_t n, const double alpha, const xparams _xparams = alglib::xdefault); void filterema(real_1d_array &x, const double alpha, const xparams _xparams = alglib::xdefault);
Examples: [1]
filterlrma function/************************************************************************* Filters: linear regression moving averages. This filter replaces array by results of LRMA(K) filter. LRMA(K) is defined as filter which, for each data point, builds linear regression model using K prevous points (point itself is included in these K points) and calculates value of this linear model at the point in question. INPUT PARAMETERS: X - array[N], array to process. It can be larger than N, in this case only first N points are processed. N - points count, N>=0 K - K>=1 (K can be larger than N , such cases will be correctly handled). Window width. K=1 corresponds to identity transformation (nothing changes). OUTPUT PARAMETERS: X - array, whose first N elements were processed with LRMA(K) NOTE 1: this function uses efficient in-place algorithm which does not allocate temporary arrays. NOTE 2: this algorithm makes only one pass through array and uses running sum to speed-up calculation of the averages. Additional measures are taken to ensure that running sum on a long sequence of zero elements will be correctly reset to zero even in the presence of round-off error. NOTE 3: this is unsymmetric version of the algorithm, which does NOT averages points after the current one. Only X[i], X[i-1], ... are used when calculating new value of X[i]. We should also note that this algorithm uses BOTH previous points and current one, i.e. new value of X[i] depends on BOTH previous point and X[i] itself. -- ALGLIB -- Copyright 25.10.2011 by Bochkanov Sergey *************************************************************************/void filterlrma(real_1d_array &x, const ae_int_t n, const ae_int_t k, const xparams _xparams = alglib::xdefault); void filterlrma(real_1d_array &x, const ae_int_t k, const xparams _xparams = alglib::xdefault);
Examples: [1]
filtersma function/************************************************************************* Filters: simple moving averages (unsymmetric). This filter replaces array by results of SMA(K) filter. SMA(K) is defined as filter which averages at most K previous points (previous - not points AROUND central point) - or less, in case of the first K-1 points. INPUT PARAMETERS: X - array[N], array to process. It can be larger than N, in this case only first N points are processed. N - points count, N>=0 K - K>=1 (K can be larger than N , such cases will be correctly handled). Window width. K=1 corresponds to identity transformation (nothing changes). OUTPUT PARAMETERS: X - array, whose first N elements were processed with SMA(K) NOTE 1: this function uses efficient in-place algorithm which does not allocate temporary arrays. NOTE 2: this algorithm makes only one pass through array and uses running sum to speed-up calculation of the averages. Additional measures are taken to ensure that running sum on a long sequence of zero elements will be correctly reset to zero even in the presence of round-off error. NOTE 3: this is unsymmetric version of the algorithm, which does NOT averages points after the current one. Only X[i], X[i-1], ... are used when calculating new value of X[i]. We should also note that this algorithm uses BOTH previous points and current one, i.e. new value of X[i] depends on BOTH previous point and X[i] itself. -- ALGLIB -- Copyright 25.10.2011 by Bochkanov Sergey *************************************************************************/void filtersma(real_1d_array &x, const ae_int_t n, const ae_int_t k, const xparams _xparams = alglib::xdefault); void filtersma(real_1d_array &x, const ae_int_t k, const xparams _xparams = alglib::xdefault);
Examples: [1]
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// Here we demonstrate EMA(0.5) filtering for time series.
//
real_1d_array x = "[5,6,7,8]";
//
// Apply filter.
// We should get [5, 5.5, 6.25, 7.125] as result
//
filterema(x, 0.5);
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [5,5.5,6.25,7.125]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// Here we demonstrate LRMA(3) filtering for time series.
//
real_1d_array x = "[7,8,8,9,12,12]";
//
// Apply filter.
// We should get [7.0000, 8.0000, 8.1667, 8.8333, 11.6667, 12.5000] as result
//
filterlrma(x, 3);
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [7.0000,8.0000,8.1667,8.8333,11.6667,12.5000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// Here we demonstrate SMA(k) filtering for time series.
//
real_1d_array x = "[5,6,7,8]";
//
// Apply filter.
// We should get [5, 5.5, 6.5, 7.5] as result
//
filtersma(x, 2);
printf("%s\n", x.tostring(4).c_str()); // EXPECTED: [5,5.5,6.5,7.5]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
fitsphere subpackagefitspherels function/************************************************************************* Fits least squares (LS) circle (or NX-dimensional sphere) to data (a set of points in NX-dimensional space). Least squares circle minimizes sum of squared deviations between distances from points to the center and some "candidate" radius, which is also fitted to the data. INPUT PARAMETERS: XY - array[NPoints,NX] (or larger), contains dataset. One row = one point in NX-dimensional space. NPoints - dataset size, NPoints>0 NX - space dimensionality, NX>0 (1, 2, 3, 4, 5 and so on) OUTPUT PARAMETERS: CX - central point for a sphere R - radius -- ALGLIB -- Copyright 07.05.2018 by Bochkanov Sergey *************************************************************************/void fitspherels(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nx, real_1d_array &cx, double &r, const xparams _xparams = alglib::xdefault);
fitspheremc function/************************************************************************* Fits minimum circumscribed (MC) circle (or NX-dimensional sphere) to data (a set of points in NX-dimensional space). INPUT PARAMETERS: XY - array[NPoints,NX] (or larger), contains dataset. One row = one point in NX-dimensional space. NPoints - dataset size, NPoints>0 NX - space dimensionality, NX>0 (1, 2, 3, 4, 5 and so on) OUTPUT PARAMETERS: CX - central point for a sphere RHi - radius NOTE: this function is an easy-to-use wrapper around more powerful "expert" function fitspherex(). This wrapper is optimized for ease of use and stability - at the cost of somewhat lower performance (we have to use very tight stopping criteria for inner optimizer because we want to make sure that it will converge on any dataset). If you are ready to experiment with settings of "expert" function, you can achieve ~2-4x speedup over standard "bulletproof" settings. -- ALGLIB -- Copyright 14.04.2017 by Bochkanov Sergey *************************************************************************/void fitspheremc(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nx, real_1d_array &cx, double &rhi, const xparams _xparams = alglib::xdefault);
fitspheremi function/************************************************************************* Fits maximum inscribed circle (or NX-dimensional sphere) to data (a set of points in NX-dimensional space). INPUT PARAMETERS: XY - array[NPoints,NX] (or larger), contains dataset. One row = one point in NX-dimensional space. NPoints - dataset size, NPoints>0 NX - space dimensionality, NX>0 (1, 2, 3, 4, 5 and so on) OUTPUT PARAMETERS: CX - central point for a sphere RLo - radius NOTE: this function is an easy-to-use wrapper around more powerful "expert" function fitspherex(). This wrapper is optimized for ease of use and stability - at the cost of somewhat lower performance (we have to use very tight stopping criteria for inner optimizer because we want to make sure that it will converge on any dataset). If you are ready to experiment with settings of "expert" function, you can achieve ~2-4x speedup over standard "bulletproof" settings. -- ALGLIB -- Copyright 14.04.2017 by Bochkanov Sergey *************************************************************************/void fitspheremi(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nx, real_1d_array &cx, double &rlo, const xparams _xparams = alglib::xdefault);
fitspheremz function/************************************************************************* Fits minimum zone circle (or NX-dimensional sphere) to data (a set of points in NX-dimensional space). INPUT PARAMETERS: XY - array[NPoints,NX] (or larger), contains dataset. One row = one point in NX-dimensional space. NPoints - dataset size, NPoints>0 NX - space dimensionality, NX>0 (1, 2, 3, 4, 5 and so on) OUTPUT PARAMETERS: CX - central point for a sphere RLo - radius of inscribed circle RHo - radius of circumscribed circle NOTE: this function is an easy-to-use wrapper around more powerful "expert" function fitspherex(). This wrapper is optimized for ease of use and stability - at the cost of somewhat lower performance (we have to use very tight stopping criteria for inner optimizer because we want to make sure that it will converge on any dataset). If you are ready to experiment with settings of "expert" function, you can achieve ~2-4x speedup over standard "bulletproof" settings. -- ALGLIB -- Copyright 14.04.2017 by Bochkanov Sergey *************************************************************************/void fitspheremz(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nx, real_1d_array &cx, double &rlo, double &rhi, const xparams _xparams = alglib::xdefault);
fitspherex function/************************************************************************* Fitting minimum circumscribed, maximum inscribed or minimum zone circles (or NX-dimensional spheres) to data (a set of points in NX-dimensional space). This is expert function which allows to tweak many parameters of underlying nonlinear solver: * stopping criteria for inner iterations * number of outer iterations You may tweak all these parameters or only some of them, leaving other ones at their default state - just specify zero value, and solver will fill it with appropriate default one. These comments also include some discussion of approach used to handle such unusual fitting problem, its stability, drawbacks of alternative methods, and convergence properties. INPUT PARAMETERS: XY - array[NPoints,NX] (or larger), contains dataset. One row = one point in NX-dimensional space. NPoints - dataset size, NPoints>0 NX - space dimensionality, NX>0 (1, 2, 3, 4, 5 and so on) ProblemType-used to encode problem type: * 0 for least squares circle * 1 for minimum circumscribed circle/sphere fitting (MC) * 2 for maximum inscribed circle/sphere fitting (MI) * 3 for minimum zone circle fitting (difference between Rhi and Rlo is minimized), denoted as MZ EpsX - stopping condition for NLC optimizer: * must be non-negative * use 0 to choose default value (1.0E-12 is used by default) * you may specify larger values, up to 1.0E-6, if you want to speed-up solver; NLC solver performs several preconditioned outer iterations, so final result typically has precision much better than EpsX. AULIts - number of outer iterations performed by NLC optimizer: * must be non-negative * use 0 to choose default value (20 is used by default) * you may specify values smaller than 20 if you want to speed up solver; 10 often results in good combination of precision and speed; sometimes you may get good results with just 6 outer iterations. Ignored for ProblemType=0. OUTPUT PARAMETERS: CX - central point for a sphere RLo - radius: * for ProblemType=2,3, radius of the inscribed sphere * for ProblemType=0 - radius of the least squares sphere * for ProblemType=1 - zero RHo - radius: * for ProblemType=1,3, radius of the circumscribed sphere * for ProblemType=0 - radius of the least squares sphere * for ProblemType=2 - zero NOTE: ON THE UNIQUENESS OF SOLUTIONS ALGLIB provides solution to several related circle fitting problems: MC (minimum circumscribed), MI (maximum inscribed) and MZ (minimum zone) fitting, LS (least squares) fitting. It is important to note that among these problems only MC and LS are convex and have unique solution independently from starting point. As for MI, it may (or may not, depending on dataset properties) have multiple solutions, and it always has one degenerate solution C=infinity which corresponds to infinitely large radius. Thus, there are no guarantees that solution to MI returned by this solver will be the best one (and no one can provide you with such guarantee because problem is NP-hard). The only guarantee you have is that this solution is locally optimal, i.e. it can not be improved by infinitesimally small tweaks in the parameters. It is also possible to "run away" to infinity when started from bad initial point located outside of point cloud (or when point cloud does not span entire circumference/surface of the sphere). Finally, MZ (minimum zone circle) stands somewhere between MC and MI in stability. It is somewhat regularized by "circumscribed" term of the merit function; however, solutions to MZ may be non-unique, and in some unlucky cases it is also possible to "run away to infinity". NOTE: ON THE NONLINEARLY CONSTRAINED PROGRAMMING APPROACH The problem formulation for MC (minimum circumscribed circle; for the sake of simplicity we omit MZ and MI here) is: [ [ ]2 ] min [ max [ XY[i]-C ] ] C [ i [ ] ] i.e. it is unconstrained nonsmooth optimization problem of finding "best" central point, with radius R being unambiguously determined from C. In order to move away from non-smoothness we use following reformulation: [ ] [ ]2 min [ R ] subject to R>=0, [ XY[i]-C ] <= R^2 C,R [ ] [ ] i.e. it becomes smooth quadratically constrained optimization problem with linear target function. Such problem statement is 100% equivalent to the original nonsmooth one, but much easier to approach. We solve it with MinNLC solver provided by ALGLIB. NOTE: ON INSTABILITY OF SEQUENTIAL LINEARIZATION APPROACH ALGLIB has nonlinearly constrained solver which proved to be stable on such problems. However, some authors proposed to linearize constraints in the vicinity of current approximation (Ci,Ri) and to get next approximate solution (Ci+1,Ri+1) as solution to linear programming problem. Obviously, LP problems are easier than nonlinearly constrained ones. Indeed, such approach to MC/MI/MZ resulted in ~10-20x increase in performance (when compared with NLC solver). However, it turned out that in some cases linearized model fails to predict correct direction for next step and tells us that we converged to solution even when we are still 2-4 digits of precision away from it. It is important that it is not failure of LP solver - it is failure of the linear model; even when solved exactly, it fails to handle subtle nonlinearities which arise near the solution. We validated it by comparing results returned by ALGLIB linear solver with that of MATLAB. In our experiments with linearization: * MC failed most often, at both realistic and synthetic datasets * MI sometimes failed, but sometimes succeeded * MZ often succeeded; our guess is that presence of two independent sets of constraints (one set for Rlo and another one for Rhi) and two terms in the target function (Rlo and Rhi) regularizes task, so when linear model fails to handle nonlinearities from Rlo, it uses Rhi as a hint (and vice versa). Because linearization approach failed to achieve stable results, we do not include it in ALGLIB. -- ALGLIB -- Copyright 14.04.2017 by Bochkanov Sergey *************************************************************************/void fitspherex(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nx, const ae_int_t problemtype, const double epsx, const ae_int_t aulits, real_1d_array &cx, double &rlo, double &rhi, const xparams _xparams = alglib::xdefault);
fresnel subpackagefresnelintegral function/************************************************************************* Fresnel integral Evaluates the Fresnel integrals x - | | C(x) = | cos(pi/2 t**2) dt, | | - 0 x - | | S(x) = | sin(pi/2 t**2) dt. | | - 0 The integrals are evaluated by a power series for x < 1. For x >= 1 auxiliary functions f(x) and g(x) are employed such that C(x) = 0.5 + f(x) sin( pi/2 x**2 ) - g(x) cos( pi/2 x**2 ) S(x) = 0.5 - f(x) cos( pi/2 x**2 ) - g(x) sin( pi/2 x**2 ) ACCURACY: Relative error. Arithmetic function domain # trials peak rms IEEE S(x) 0, 10 10000 2.0e-15 3.2e-16 IEEE C(x) 0, 10 10000 1.8e-15 3.3e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier *************************************************************************/void fresnelintegral(const double x, double &c, double &s, const xparams _xparams = alglib::xdefault);
gammafunc subpackagegammafunction function/************************************************************************* Gamma function Input parameters: X - argument Domain: 0 < X < 171.6 -170 < X < 0, X is not an integer. Relative error: arithmetic domain # trials peak rms IEEE -170,-33 20000 2.3e-15 3.3e-16 IEEE -33, 33 20000 9.4e-16 2.2e-16 IEEE 33, 171.6 20000 2.3e-15 3.2e-16 Cephes Math Library Release 2.8: June, 2000 Original copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier Translated to AlgoPascal by Bochkanov Sergey (2005, 2006, 2007). *************************************************************************/double gammafunction(const double x, const xparams _xparams = alglib::xdefault);
lngamma function/************************************************************************* Natural logarithm of gamma function Input parameters: X - argument Result: logarithm of the absolute value of the Gamma(X). Output parameters: SgnGam - sign(Gamma(X)) Domain: 0 < X < 2.55e305 -2.55e305 < X < 0, X is not an integer. ACCURACY: arithmetic domain # trials peak rms IEEE 0, 3 28000 5.4e-16 1.1e-16 IEEE 2.718, 2.556e305 40000 3.5e-16 8.3e-17 The error criterion was relative when the function magnitude was greater than one but absolute when it was less than one. The following test used the relative error criterion, though at certain points the relative error could be much higher than indicated. IEEE -200, -4 10000 4.8e-16 1.3e-16 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier Translated to AlgoPascal by Bochkanov Sergey (2005, 2006, 2007). *************************************************************************/double lngamma(const double x, double &sgngam, const xparams _xparams = alglib::xdefault);
gkq subpackagegkqgenerategaussjacobi function/************************************************************************* Returns Gauss and Gauss-Kronrod nodes/weights for Gauss-Jacobi quadrature on [-1,1] with weight function W(x)=Power(1-x,Alpha)*Power(1+x,Beta). INPUT PARAMETERS: N - number of Kronrod nodes, must be odd number, >=3. Alpha - power-law coefficient, Alpha>-1 Beta - power-law coefficient, Beta>-1 OUTPUT PARAMETERS: Info - error code: * -5 no real and positive Gauss-Kronrod formula can be created for such a weight function with a given number of nodes. * -4 an error was detected when calculating weights/nodes. Alpha or Beta are too close to -1 to obtain weights/nodes with high enough accuracy, or, may be, N is too large. Try to use multiple precision version. * -3 internal eigenproblem solver hasn't converged * -1 incorrect N was passed * +1 OK * +2 OK, but quadrature rule have exterior nodes, x[0]<-1 or x[n-1]>+1 X - array[0..N-1] - array of quadrature nodes, ordered in ascending order. WKronrod - array[0..N-1] - Kronrod weights WGauss - array[0..N-1] - Gauss weights (interleaved with zeros corresponding to extended Kronrod nodes). -- ALGLIB -- Copyright 12.05.2009 by Bochkanov Sergey *************************************************************************/void gkqgenerategaussjacobi(const ae_int_t n, const double alpha, const double beta, ae_int_t &info, real_1d_array &x, real_1d_array &wkronrod, real_1d_array &wgauss, const xparams _xparams = alglib::xdefault);
gkqgenerategausslegendre function/************************************************************************* Returns Gauss and Gauss-Kronrod nodes/weights for Gauss-Legendre quadrature with N points. GKQLegendreCalc (calculation) or GKQLegendreTbl (precomputed table) is used depending on machine precision and number of nodes. INPUT PARAMETERS: N - number of Kronrod nodes, must be odd number, >=3. OUTPUT PARAMETERS: Info - error code: * -4 an error was detected when calculating weights/nodes. N is too large to obtain weights/nodes with high enough accuracy. Try to use multiple precision version. * -3 internal eigenproblem solver hasn't converged * -1 incorrect N was passed * +1 OK X - array[0..N-1] - array of quadrature nodes, ordered in ascending order. WKronrod - array[0..N-1] - Kronrod weights WGauss - array[0..N-1] - Gauss weights (interleaved with zeros corresponding to extended Kronrod nodes). -- ALGLIB -- Copyright 12.05.2009 by Bochkanov Sergey *************************************************************************/void gkqgenerategausslegendre(const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &wkronrod, real_1d_array &wgauss, const xparams _xparams = alglib::xdefault);
gkqgeneraterec function/************************************************************************* Computation of nodes and weights of a Gauss-Kronrod quadrature formula The algorithm generates the N-point Gauss-Kronrod quadrature formula with weight function given by coefficients alpha and beta of a recurrence relation which generates a system of orthogonal polynomials: P-1(x) = 0 P0(x) = 1 Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x) and zero moment Mu0 Mu0 = integral(W(x)dx,a,b) INPUT PARAMETERS: Alpha - alpha coefficients, array[0..floor(3*K/2)]. Beta - beta coefficients, array[0..ceil(3*K/2)]. Beta[0] is not used and may be arbitrary. Beta[I]>0. Mu0 - zeroth moment of the weight function. N - number of nodes of the Gauss-Kronrod quadrature formula, N >= 3, N = 2*K+1. OUTPUT PARAMETERS: Info - error code: * -5 no real and positive Gauss-Kronrod formula can be created for such a weight function with a given number of nodes. * -4 N is too large, task may be ill conditioned - x[i]=x[i+1] found. * -3 internal eigenproblem solver hasn't converged * -2 Beta[i]<=0 * -1 incorrect N was passed * +1 OK X - array[0..N-1] - array of quadrature nodes, in ascending order. WKronrod - array[0..N-1] - Kronrod weights WGauss - array[0..N-1] - Gauss weights (interleaved with zeros corresponding to extended Kronrod nodes). -- ALGLIB -- Copyright 08.05.2009 by Bochkanov Sergey *************************************************************************/void gkqgeneraterec(const real_1d_array &alpha, const real_1d_array &beta, const double mu0, const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &wkronrod, real_1d_array &wgauss, const xparams _xparams = alglib::xdefault);
gkqlegendrecalc function/************************************************************************* Returns Gauss and Gauss-Kronrod nodes for quadrature with N points. Reduction to tridiagonal eigenproblem is used. INPUT PARAMETERS: N - number of Kronrod nodes, must be odd number, >=3. OUTPUT PARAMETERS: Info - error code: * -4 an error was detected when calculating weights/nodes. N is too large to obtain weights/nodes with high enough accuracy. Try to use multiple precision version. * -3 internal eigenproblem solver hasn't converged * -1 incorrect N was passed * +1 OK X - array[0..N-1] - array of quadrature nodes, ordered in ascending order. WKronrod - array[0..N-1] - Kronrod weights WGauss - array[0..N-1] - Gauss weights (interleaved with zeros corresponding to extended Kronrod nodes). -- ALGLIB -- Copyright 12.05.2009 by Bochkanov Sergey *************************************************************************/void gkqlegendrecalc(const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &wkronrod, real_1d_array &wgauss, const xparams _xparams = alglib::xdefault);
gkqlegendretbl function/************************************************************************* Returns Gauss and Gauss-Kronrod nodes for quadrature with N points using pre-calculated table. Nodes/weights were computed with accuracy up to 1.0E-32 (if MPFR version of ALGLIB is used). In standard double precision accuracy reduces to something about 2.0E-16 (depending on your compiler's handling of long floating point constants). INPUT PARAMETERS: N - number of Kronrod nodes. N can be 15, 21, 31, 41, 51, 61. OUTPUT PARAMETERS: X - array[0..N-1] - array of quadrature nodes, ordered in ascending order. WKronrod - array[0..N-1] - Kronrod weights WGauss - array[0..N-1] - Gauss weights (interleaved with zeros corresponding to extended Kronrod nodes). -- ALGLIB -- Copyright 12.05.2009 by Bochkanov Sergey *************************************************************************/void gkqlegendretbl(const ae_int_t n, real_1d_array &x, real_1d_array &wkronrod, real_1d_array &wgauss, double &eps, const xparams _xparams = alglib::xdefault);
gq subpackagegqgenerategausshermite function/************************************************************************* Returns nodes/weights for Gauss-Hermite quadrature on (-inf,+inf) with weight function W(x)=Exp(-x*x) INPUT PARAMETERS: N - number of nodes, >=1 OUTPUT PARAMETERS: Info - error code: * -4 an error was detected when calculating weights/nodes. May be, N is too large. Try to use multiple precision version. * -3 internal eigenproblem solver hasn't converged * -1 incorrect N/Alpha was passed * +1 OK X - array[0..N-1] - array of quadrature nodes, in ascending order. W - array[0..N-1] - array of quadrature weights. -- ALGLIB -- Copyright 12.05.2009 by Bochkanov Sergey *************************************************************************/void gqgenerategausshermite(const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams = alglib::xdefault);
gqgenerategaussjacobi function/************************************************************************* Returns nodes/weights for Gauss-Jacobi quadrature on [-1,1] with weight function W(x)=Power(1-x,Alpha)*Power(1+x,Beta). INPUT PARAMETERS: N - number of nodes, >=1 Alpha - power-law coefficient, Alpha>-1 Beta - power-law coefficient, Beta>-1 OUTPUT PARAMETERS: Info - error code: * -4 an error was detected when calculating weights/nodes. Alpha or Beta are too close to -1 to obtain weights/nodes with high enough accuracy, or, may be, N is too large. Try to use multiple precision version. * -3 internal eigenproblem solver hasn't converged * -1 incorrect N/Alpha/Beta was passed * +1 OK X - array[0..N-1] - array of quadrature nodes, in ascending order. W - array[0..N-1] - array of quadrature weights. -- ALGLIB -- Copyright 12.05.2009 by Bochkanov Sergey *************************************************************************/void gqgenerategaussjacobi(const ae_int_t n, const double alpha, const double beta, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams = alglib::xdefault);
gqgenerategausslaguerre function/************************************************************************* Returns nodes/weights for Gauss-Laguerre quadrature on [0,+inf) with weight function W(x)=Power(x,Alpha)*Exp(-x) INPUT PARAMETERS: N - number of nodes, >=1 Alpha - power-law coefficient, Alpha>-1 OUTPUT PARAMETERS: Info - error code: * -4 an error was detected when calculating weights/nodes. Alpha is too close to -1 to obtain weights/nodes with high enough accuracy or, may be, N is too large. Try to use multiple precision version. * -3 internal eigenproblem solver hasn't converged * -1 incorrect N/Alpha was passed * +1 OK X - array[0..N-1] - array of quadrature nodes, in ascending order. W - array[0..N-1] - array of quadrature weights. -- ALGLIB -- Copyright 12.05.2009 by Bochkanov Sergey *************************************************************************/void gqgenerategausslaguerre(const ae_int_t n, const double alpha, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams = alglib::xdefault);
gqgenerategausslegendre function/************************************************************************* Returns nodes/weights for Gauss-Legendre quadrature on [-1,1] with N nodes. INPUT PARAMETERS: N - number of nodes, >=1 OUTPUT PARAMETERS: Info - error code: * -4 an error was detected when calculating weights/nodes. N is too large to obtain weights/nodes with high enough accuracy. Try to use multiple precision version. * -3 internal eigenproblem solver hasn't converged * -1 incorrect N was passed * +1 OK X - array[0..N-1] - array of quadrature nodes, in ascending order. W - array[0..N-1] - array of quadrature weights. -- ALGLIB -- Copyright 12.05.2009 by Bochkanov Sergey *************************************************************************/void gqgenerategausslegendre(const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams = alglib::xdefault);
gqgenerategausslobattorec function/************************************************************************* Computation of nodes and weights for a Gauss-Lobatto quadrature formula The algorithm generates the N-point Gauss-Lobatto quadrature formula with weight function given by coefficients alpha and beta of a recurrence which generates a system of orthogonal polynomials. P-1(x) = 0 P0(x) = 1 Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x) and zeroth moment Mu0 Mu0 = integral(W(x)dx,a,b) INPUT PARAMETERS: Alpha - array[0..N-2], alpha coefficients Beta - array[0..N-2], beta coefficients. Zero-indexed element is not used, may be arbitrary. Beta[I]>0 Mu0 - zeroth moment of the weighting function. A - left boundary of the integration interval. B - right boundary of the integration interval. N - number of nodes of the quadrature formula, N>=3 (including the left and right boundary nodes). OUTPUT PARAMETERS: Info - error code: * -3 internal eigenproblem solver hasn't converged * -2 Beta[i]<=0 * -1 incorrect N was passed * 1 OK X - array[0..N-1] - array of quadrature nodes, in ascending order. W - array[0..N-1] - array of quadrature weights. -- ALGLIB -- Copyright 2005-2009 by Bochkanov Sergey *************************************************************************/void gqgenerategausslobattorec(const real_1d_array &alpha, const real_1d_array &beta, const double mu0, const double a, const double b, const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams = alglib::xdefault);
gqgenerategaussradaurec function/************************************************************************* Computation of nodes and weights for a Gauss-Radau quadrature formula The algorithm generates the N-point Gauss-Radau quadrature formula with weight function given by the coefficients alpha and beta of a recurrence which generates a system of orthogonal polynomials. P-1(x) = 0 P0(x) = 1 Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x) and zeroth moment Mu0 Mu0 = integral(W(x)dx,a,b) INPUT PARAMETERS: Alpha - array[0..N-2], alpha coefficients. Beta - array[0..N-1], beta coefficients Zero-indexed element is not used. Beta[I]>0 Mu0 - zeroth moment of the weighting function. A - left boundary of the integration interval. N - number of nodes of the quadrature formula, N>=2 (including the left boundary node). OUTPUT PARAMETERS: Info - error code: * -3 internal eigenproblem solver hasn't converged * -2 Beta[i]<=0 * -1 incorrect N was passed * 1 OK X - array[0..N-1] - array of quadrature nodes, in ascending order. W - array[0..N-1] - array of quadrature weights. -- ALGLIB -- Copyright 2005-2009 by Bochkanov Sergey *************************************************************************/void gqgenerategaussradaurec(const real_1d_array &alpha, const real_1d_array &beta, const double mu0, const double a, const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams = alglib::xdefault);
gqgeneraterec function/************************************************************************* Computation of nodes and weights for a Gauss quadrature formula The algorithm generates the N-point Gauss quadrature formula with weight function given by coefficients alpha and beta of a recurrence relation which generates a system of orthogonal polynomials: P-1(x) = 0 P0(x) = 1 Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x) and zeroth moment Mu0 Mu0 = integral(W(x)dx,a,b) INPUT PARAMETERS: Alpha - array[0..N-1], alpha coefficients Beta - array[0..N-1], beta coefficients Zero-indexed element is not used and may be arbitrary. Beta[I]>0. Mu0 - zeroth moment of the weight function. N - number of nodes of the quadrature formula, N>=1 OUTPUT PARAMETERS: Info - error code: * -3 internal eigenproblem solver hasn't converged * -2 Beta[i]<=0 * -1 incorrect N was passed * 1 OK X - array[0..N-1] - array of quadrature nodes, in ascending order. W - array[0..N-1] - array of quadrature weights. -- ALGLIB -- Copyright 2005-2009 by Bochkanov Sergey *************************************************************************/void gqgeneraterec(const real_1d_array &alpha, const real_1d_array &beta, const double mu0, const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams = alglib::xdefault);
hermite subpackagehermitecalculate function/************************************************************************* Calculation of the value of the Hermite polynomial. Parameters: n - degree, n>=0 x - argument Result: the value of the Hermite polynomial Hn at x *************************************************************************/double hermitecalculate(const ae_int_t n, const double x, const xparams _xparams = alglib::xdefault);
hermitecoefficients function/************************************************************************* Representation of Hn as C[0] + C[1]*X + ... + C[N]*X^N Input parameters: N - polynomial degree, n>=0 Output parameters: C - coefficients *************************************************************************/void hermitecoefficients(const ae_int_t n, real_1d_array &c, const xparams _xparams = alglib::xdefault);
hermitesum function/************************************************************************* Summation of Hermite polynomials using Clenshaw's recurrence formula. This routine calculates c[0]*H0(x) + c[1]*H1(x) + ... + c[N]*HN(x) Parameters: n - degree, n>=0 x - argument Result: the value of the Hermite polynomial at x *************************************************************************/double hermitesum(const real_1d_array &c, const ae_int_t n, const double x, const xparams _xparams = alglib::xdefault);
hqrnd subpackagehqrndstate class/************************************************************************* 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. *************************************************************************/class hqrndstate { public: hqrndstate(); hqrndstate(const hqrndstate &rhs); hqrndstate& operator=(const hqrndstate &rhs); virtual ~hqrndstate(); };
hqrndcontinuous function/************************************************************************* 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, const real_1d_array &x, const ae_int_t n, const xparams _xparams = alglib::xdefault);
hqrnddiscrete function/************************************************************************* 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, const real_1d_array &x, const ae_int_t n, const xparams _xparams = alglib::xdefault);
hqrndexponential function/************************************************************************* 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, const double lambdav, const xparams _xparams = alglib::xdefault);
hqrndnormal function/************************************************************************* 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, const xparams _xparams = alglib::xdefault);
hqrndnormal2 function/************************************************************************* 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, const xparams _xparams = alglib::xdefault);
hqrndnormalm function/************************************************************************* Random number generator: matrix with random entries (normal distribution) This function generates MxN random matrix. State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/void hqrndnormalm(hqrndstate &state, const ae_int_t m, const ae_int_t n, real_2d_array &x, const xparams _xparams = alglib::xdefault);
hqrndnormalv function/************************************************************************* Random number generator: vector with random entries (normal distribution) This function generates N random numbers from normal distribution. State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/void hqrndnormalv(hqrndstate &state, const ae_int_t n, real_1d_array &x, const xparams _xparams = alglib::xdefault);
hqrndrandomize function/************************************************************************* 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 = alglib::xdefault);
hqrndseed function/************************************************************************* 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 = alglib::xdefault);
hqrnduniformi function/************************************************************************* 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, const ae_int_t n, const xparams _xparams = alglib::xdefault);
hqrnduniformr function/************************************************************************* 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, const xparams _xparams = alglib::xdefault);
hqrndunit2 function/************************************************************************* 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, const xparams _xparams = alglib::xdefault);
ibetaf subpackageincompletebeta function/************************************************************************* Incomplete beta integral Returns incomplete beta integral of the arguments, evaluated from zero to x. The function is defined as x - - | (a+b) | | a-1 b-1 ----------- | t (1-t) dt. - - | | | (a) | (b) - 0 The domain of definition is 0 <= x <= 1. In this implementation a and b are restricted to positive values. The integral from x to 1 may be obtained by the symmetry relation 1 - incbet( a, b, x ) = incbet( b, a, 1-x ). The integral is evaluated by a continued fraction expansion or, when b*x is small, by a power series. ACCURACY: Tested at uniformly distributed random points (a,b,x) with a and b in "domain" and x between 0 and 1. Relative error arithmetic domain # trials peak rms IEEE 0,5 10000 6.9e-15 4.5e-16 IEEE 0,85 250000 2.2e-13 1.7e-14 IEEE 0,1000 30000 5.3e-12 6.3e-13 IEEE 0,10000 250000 9.3e-11 7.1e-12 IEEE 0,100000 10000 8.7e-10 4.8e-11 Outputs smaller than the IEEE gradual underflow threshold were excluded from these statistics. Cephes Math Library, Release 2.8: June, 2000 Copyright 1984, 1995, 2000 by Stephen L. Moshier *************************************************************************/double incompletebeta(const double a, const double b, const double x, const xparams _xparams = alglib::xdefault);
invincompletebeta function/************************************************************************* Inverse of imcomplete beta integral Given y, the function finds x such that incbet( a, b, x ) = y . The routine performs interval halving or Newton iterations to find the root of incbet(a,b,x) - y = 0. ACCURACY: Relative error: x a,b arithmetic domain domain # trials peak rms IEEE 0,1 .5,10000 50000 5.8e-12 1.3e-13 IEEE 0,1 .25,100 100000 1.8e-13 3.9e-15 IEEE 0,1 0,5 50000 1.1e-12 5.5e-15 With a and b constrained to half-integer or integer values: IEEE 0,1 .5,10000 50000 5.8e-12 1.1e-13 IEEE 0,1 .5,100 100000 1.7e-14 7.9e-16 With a = .5, b constrained to half-integer or integer values: IEEE 0,1 .5,10000 10000 8.3e-11 1.0e-11 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1996, 2000 by Stephen L. Moshier *************************************************************************/double invincompletebeta(const double a, const double b, const double y, const xparams _xparams = alglib::xdefault);
idw subpackage| idw_d_mstab | Simple model built with IDW-MSTAB algorithm | |
| idw_d_serialize | IDW model serialization/unserialization |
idwbuilder class/************************************************************************* Builder object used to generate IDW (Inverse Distance Weighting) model. *************************************************************************/class idwbuilder { public: idwbuilder(); idwbuilder(const idwbuilder &rhs); idwbuilder& operator=(const idwbuilder &rhs); virtual ~idwbuilder(); };
idwcalcbuffer class/************************************************************************* Buffer object which is used to perform evaluation requests in the multithreaded mode (multiple threads working with same IDW object). This object should be created with idwcreatecalcbuffer(). *************************************************************************/class idwcalcbuffer { public: idwcalcbuffer(); idwcalcbuffer(const idwcalcbuffer &rhs); idwcalcbuffer& operator=(const idwcalcbuffer &rhs); virtual ~idwcalcbuffer(); };
idwmodel class/************************************************************************* IDW (Inverse Distance Weighting) model object. *************************************************************************/class idwmodel { public: idwmodel(); idwmodel(const idwmodel &rhs); idwmodel& operator=(const idwmodel &rhs); virtual ~idwmodel(); };
idwreport class/************************************************************************* IDW fitting report: rmserror RMS error avgerror average error maxerror maximum error r2 coefficient of determination, R-squared, 1-RSS/TSS *************************************************************************/class idwreport { public: idwreport(); idwreport(const idwreport &rhs); idwreport& operator=(const idwreport &rhs); virtual ~idwreport(); double rmserror; double avgerror; double maxerror; double r2; };
idwbuildercreate function/************************************************************************* This subroutine creates builder object used to generate IDW model from irregularly sampled (scattered) dataset. Multidimensional scalar/vector- -valued are supported. Builder object is used to fit model to data as follows: * builder object is created with idwbuildercreate() function * dataset is added with idwbuildersetpoints() function * one of the modern IDW algorithms is chosen with either: * idwbuildersetalgomstab() - Multilayer STABilized algorithm (interpolation) Alternatively, one of the textbook algorithms can be chosen (not recommended): * idwbuildersetalgotextbookshepard() - textbook Shepard algorithm * idwbuildersetalgotextbookmodshepard()-textbook modified Shepard algorithm * finally, model construction is performed with idwfit() function. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: NX - dimensionality of the argument, NX>=1 NY - dimensionality of the function being modeled, NY>=1; NY=1 corresponds to classic scalar function, NY>=1 corresponds to vector-valued function. OUTPUT PARAMETERS: State- builder object -- ALGLIB PROJECT -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/void idwbuildercreate(const ae_int_t nx, const ae_int_t ny, idwbuilder &state, const xparams _xparams = alglib::xdefault);
idwbuildersetalgomstab function/************************************************************************* This function sets IDW model construction algorithm to the Multilayer Stabilized IDW method (IDW-MSTAB), a latest incarnation of the inverse distance weighting interpolation which fixes shortcomings of the original and modified Shepard's variants. The distinctive features of IDW-MSTAB are: 1) exact interpolation is pursued (as opposed to fitting and noise suppression) 2) improved robustness when compared with that of other algorithms: * MSTAB shows almost no strange fitting artifacts like ripples and sharp spikes (unlike N-dimensional splines and HRBFs) * MSTAB does not return function values far from the interval spanned by the dataset; say, if all your points have |f|<=1, you can be sure that model value won't deviate too much from [-1,+1] 3) good model construction time competing with that of HRBFs and bicubic splines 4) ability to work with any number of dimensions, starting from NX=1 The drawbacks of IDW-MSTAB (and all IDW algorithms in general) are: 1) dependence of the model evaluation time on the search radius 2) bad extrapolation properties, models built by this method are usually conservative in their predictions Thus, IDW-MSTAB is a good "default" option if you want to perform scattered multidimensional interpolation. Although it has its drawbacks, it is easy to use and robust, which makes it a good first step. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: State - builder object SRad - initial search radius, SRad>0 is required. A model value is obtained by "smart" averaging of the dataset points within search radius. NOTE 1: IDW interpolation can correctly handle ANY dataset, including datasets with non-distinct points. In case non-distinct points are found, an average value for this point will be calculated. NOTE 2: the memory requirements for model storage are O(NPoints*NLayers). The model construction needs twice as much memory as model storage. NOTE 3: by default 16 IDW layers are built which is enough for most cases. You can change this parameter with idwbuildersetnlayers() method. Larger values may be necessary if you need to reproduce extrafine details at distances smaller than SRad/65536. Smaller value may be necessary if you have to save memory and computing time, and ready to sacrifice some model quality. ALGORITHM DESCRIPTION ALGLIB implementation of IDW is somewhat similar to the modified Shepard's method (one with search radius R) but overcomes several of its drawbacks, namely: 1) a tendency to show stepwise behavior for uniform datasets 2) a tendency to show terrible interpolation properties for highly nonuniform datasets which often arise in geospatial tasks (function values are densely sampled across multiple separated "tracks") IDW-MSTAB method performs several passes over dataset and builds a sequence of progressively refined IDW models (layers), which starts from one with largest search radius SRad and continues to smaller search radii until required number of layers is built. Highest layers reproduce global behavior of the target function at larger distances whilst lower layers reproduce fine details at smaller distances. Each layer is an IDW model built with following modifications: * weights go to zero when distance approach to the current search radius * an additional regularizing term is added to the distance: w=1/(d^2+lambda) * an additional fictional term with unit weight and zero function value is added in order to promote continuity properties at the isolated and boundary points By default, 16 layers is built, which is enough for most cases. You can change this parameter with idwbuildersetnlayers() method. -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/void idwbuildersetalgomstab(idwbuilder &state, const double srad, const xparams _xparams = alglib::xdefault);
idwbuildersetalgotextbookmodshepard function/************************************************************************* This function sets IDW model construction algorithm to the 'textbook' modified Shepard's algorithm with user-specified search radius. IMPORTANT: we do NOT recommend using textbook IDW algorithms because they have terrible interpolation properties. Use MSTAB in all cases. INPUT PARAMETERS: State - builder object R - search radius NOTE 1: IDW interpolation can correctly handle ANY dataset, including datasets with non-distinct points. In case non-distinct points are found, an average value for this point will be calculated. -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/void idwbuildersetalgotextbookmodshepard(idwbuilder &state, const double r, const xparams _xparams = alglib::xdefault);
idwbuildersetalgotextbookshepard function/************************************************************************* This function sets IDW model construction algorithm to the textbook Shepard's algorithm with custom (user-specified) power parameter. IMPORTANT: we do NOT recommend using textbook IDW algorithms because they have terrible interpolation properties. Use MSTAB in all cases. INPUT PARAMETERS: State - builder object P - power parameter, P>0; good value to start with is 2.0 NOTE 1: IDW interpolation can correctly handle ANY dataset, including datasets with non-distinct points. In case non-distinct points are found, an average value for this point will be calculated. -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/void idwbuildersetalgotextbookshepard(idwbuilder &state, const double p, const xparams _xparams = alglib::xdefault);
idwbuildersetconstterm function/************************************************************************* This function sets constant prior term (model value at infinity). Constant prior term is determined as mean value over dataset. INPUT PARAMETERS: S - spline builder -- ALGLIB -- Copyright 29.10.2018 by Bochkanov Sergey *************************************************************************/void idwbuildersetconstterm(idwbuilder &state, const xparams _xparams = alglib::xdefault);
idwbuildersetnlayers function/************************************************************************* This function changes number of layers used by IDW-MSTAB algorithm. The more layers you have, the finer details can be reproduced with IDW model. The less layers you have, the less memory and CPU time is consumed by the model. Memory consumption grows linearly with layers count, running time grows sub-linearly. The default number of layers is 16, which allows you to reproduce details at distance down to SRad/65536. You will rarely need to change it. INPUT PARAMETERS: State - builder object NLayers - NLayers>=1, the number of layers used by the model. -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/void idwbuildersetnlayers(idwbuilder &state, const ae_int_t nlayers, const xparams _xparams = alglib::xdefault);
idwbuildersetpoints function/************************************************************************* This function adds dataset to the builder object. This function overrides results of the previous calls, i.e. multiple calls of this function will result in only the last set being added. INPUT PARAMETERS: State - builder object XY - points, array[N,NX+NY]. One row corresponds to one point in the dataset. First NX elements are coordinates, next NY elements are function values. Array may be larger than specified, in this case only leading [N,NX+NY] elements will be used. N - number of points in the dataset, N>=0. -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/void idwbuildersetpoints(idwbuilder &state, const real_2d_array &xy, const ae_int_t n, const xparams _xparams = alglib::xdefault); void idwbuildersetpoints(idwbuilder &state, const real_2d_array &xy, const xparams _xparams = alglib::xdefault);
idwbuildersetuserterm function/************************************************************************* This function sets prior term (model value at infinity) as user-specified value. INPUT PARAMETERS: S - spline builder V - value for user-defined prior NOTE: for vector-valued models all components of the prior are set to same user-specified value -- ALGLIB -- Copyright 29.10.2018 by Bochkanov Sergey *************************************************************************/void idwbuildersetuserterm(idwbuilder &state, const double v, const xparams _xparams = alglib::xdefault);
idwbuildersetzeroterm function/************************************************************************* This function sets zero prior term (model value at infinity). INPUT PARAMETERS: S - spline builder -- ALGLIB -- Copyright 29.10.2018 by Bochkanov Sergey *************************************************************************/void idwbuildersetzeroterm(idwbuilder &state, const xparams _xparams = alglib::xdefault);
idwcalc function/************************************************************************* This function calculates values of the IDW model at the given point. This is general function which can be used for arbitrary NX (dimension of the space of arguments) and NY (dimension of the function itself). However when you have NY=1 you may find more convenient to use idwcalc1(), idwcalc2() or idwcalc3(). NOTE: this function modifies internal temporaries of the IDW model, thus IT IS NOT THREAD-SAFE! If you want to perform parallel model evaluation from the multiple threads, use idwtscalcbuf() with per- thread buffer object. INPUT PARAMETERS: S - IDW model X - coordinates, array[NX]. X may have more than NX elements, in this case only leading NX will be used. OUTPUT PARAMETERS: Y - function value, array[NY]. Y is out-parameter and will be reallocated after call to this function. In case you want to reuse previously allocated Y, you may use idwcalcbuf(), which reallocates Y only when it is too small. -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/void idwcalc(idwmodel &s, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
idwcalc1 function/************************************************************************* IDW interpolation: scalar target, 1-dimensional argument NOTE: this function modifies internal temporaries of the IDW model, thus IT IS NOT THREAD-SAFE! If you want to perform parallel model evaluation from the multiple threads, use idwtscalcbuf() with per- thread buffer object. INPUT PARAMETERS: S - IDW interpolant built with IDW builder X0 - argument value Result: IDW interpolant S(X0) -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/double idwcalc1(idwmodel &s, const double x0, const xparams _xparams = alglib::xdefault);
idwcalc2 function/************************************************************************* IDW interpolation: scalar target, 2-dimensional argument NOTE: this function modifies internal temporaries of the IDW model, thus IT IS NOT THREAD-SAFE! If you want to perform parallel model evaluation from the multiple threads, use idwtscalcbuf() with per- thread buffer object. INPUT PARAMETERS: S - IDW interpolant built with IDW builder X0, X1 - argument value Result: IDW interpolant S(X0,X1) -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/double idwcalc2(idwmodel &s, const double x0, const double x1, const xparams _xparams = alglib::xdefault);
idwcalc3 function/************************************************************************* IDW interpolation: scalar target, 3-dimensional argument NOTE: this function modifies internal temporaries of the IDW model, thus IT IS NOT THREAD-SAFE! If you want to perform parallel model evaluation from the multiple threads, use idwtscalcbuf() with per- thread buffer object. INPUT PARAMETERS: S - IDW interpolant built with IDW builder X0,X1,X2- argument value Result: IDW interpolant S(X0,X1,X2) -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/double idwcalc3(idwmodel &s, const double x0, const double x1, const double x2, const xparams _xparams = alglib::xdefault);
idwcalcbuf function/************************************************************************* This function calculates values of the IDW model at the given point. Same as idwcalc(), but does not reallocate Y when in is large enough to store function values. NOTE: this function modifies internal temporaries of the IDW model, thus IT IS NOT THREAD-SAFE! If you want to perform parallel model evaluation from the multiple threads, use idwtscalcbuf() with per- thread buffer object. INPUT PARAMETERS: S - IDW model X - coordinates, array[NX]. X may have more than NX elements, in this case only leading NX will be used. Y - possibly preallocated array OUTPUT PARAMETERS: Y - function value, array[NY]. Y is not reallocated when it is larger than NY. -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/void idwcalcbuf(idwmodel &s, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
idwcreatecalcbuffer function/************************************************************************* This function creates buffer structure which can be used to perform parallel IDW model evaluations (with one IDW model instance being used from multiple threads, as long as different threads use different instances of buffer). This buffer object can be used with idwtscalcbuf() function (here "ts" stands for "thread-safe", "buf" is a suffix which denotes function which reuses previously allocated output space). How to use it: * create IDW model structure or load it from file * call idwcreatecalcbuffer(), once per thread working with IDW model (you should call this function only AFTER model initialization, see below for more information) * call idwtscalcbuf() from different threads, with each thread working with its own copy of buffer object. INPUT PARAMETERS S - IDW model OUTPUT PARAMETERS Buf - external buffer. IMPORTANT: buffer object should be used only with IDW model object which was used to initialize buffer. Any attempt to use buffer with different object is dangerous - you may get memory violation error because sizes of internal arrays do not fit to dimensions of the IDW structure. IMPORTANT: you should call this function only for model which was built with model builder (or unserialized from file). Sizes of some internal structures are determined only after model is built, so buffer object created before model construction stage will be useless (and any attempt to use it will result in exception). -- ALGLIB -- Copyright 22.10.2018 by Sergey Bochkanov *************************************************************************/void idwcreatecalcbuffer(const idwmodel &s, idwcalcbuffer &buf, const xparams _xparams = alglib::xdefault);
idwfit function/************************************************************************* This function fits IDW model to the dataset using current IDW construction algorithm. A model being built and fitting report are returned. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: State - builder object OUTPUT PARAMETERS: Model - an IDW model built with current algorithm Rep - model fitting report, fields of this structure contain information about average fitting errors. NOTE: although IDW-MSTAB algorithm is an interpolation method, i.e. it tries to fit the model exactly, it can handle datasets with non- distinct points which can not be fit exactly; in such cases least- squares fitting is performed. -- ALGLIB -- Copyright 22.10.2018 by Bochkanov Sergey *************************************************************************/void idwfit(idwbuilder &state, idwmodel &model, idwreport &rep, const xparams _xparams = alglib::xdefault);
idwgridcalc2v function/************************************************************************* This function calculates values of an IDW model at a regular grid, which has N0*N1 points, with Point[I,J] = (X0[I], X1[J]). Vector-valued IDW models are supported. This function returns 0.0 when: * the model is not initialized * NX<>2 ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. NOTE: Parallel processing is implemented only for modern (MSTAB) IDW's. INPUT PARAMETERS: S - IDW model, used in read-only mode, can be shared between multiple invocations of this function from multiple threads. X0 - array of grid nodes, first coordinates, array[N0]. Must be ordered by ascending. Exception is generated if the array is not correctly ordered. N0 - grid size (number of nodes) in the first dimension, N0>=1 X1 - array of grid nodes, second coordinates, array[N1] Must be ordered by ascending. Exception is generated if the array is not correctly ordered. N1 - grid size (number of nodes) in the second dimension, N1>=1 OUTPUT PARAMETERS: Y - function values, array[NY*N0*N1], where NY is a number of "output" vector values (this function supports vector- valued IDW models). Y is out-variable and is reallocated by this function. Y[K+NY*(I0+I1*N0)]=F_k(X0[I0],X1[I1]), for: * K=0...NY-1 * I0=0...N0-1 * I1=0...N1-1 NOTE: this function supports weakly ordered grid nodes, i.e. you may have X[i]=X[i+1] for some i. It does not provide you any performance benefits due to duplication of points, just convenience and flexibility. NOTE: this function is re-entrant, i.e. you may use same idwmodel structure in multiple threads calling this function for different grids. NOTE: if you need function values on some subset of regular grid, which may be described as "several compact and dense islands", you may use idwgridcalc2vsubset(). -- ALGLIB -- Copyright 24.11.2023 by Bochkanov Sergey *************************************************************************/void idwgridcalc2v(const idwmodel &s, const real_1d_array &x0, const ae_int_t n0, const real_1d_array &x1, const ae_int_t n1, real_1d_array &y, const xparams _xparams = alglib::xdefault);
idwgridcalc2vsubset function/************************************************************************* This function calculates values of an IDW model at some subset of a regular grid: * the grid has N0*N1 points, with Point[I,J] = (X0[I], X1[J]) * only values at some subset of the grid are required Vector-valued IDW models are supported. This function returns 0.0 when: * the model is not initialized * NX<>2 ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. NOTE: Parallel processing is implemented only for modern (MSTAB) IDW's. INPUT PARAMETERS: S - IDW model, used in read-only mode, can be shared between multiple invocations of this function from multiple threads. X0 - array of grid nodes, first coordinates, array[N0]. Must be ordered by ascending. Exception is generated if the array is not correctly ordered. N0 - grid size (number of nodes) in the first dimension, N0>=1 X1 - array of grid nodes, second coordinates, array[N1] Must be ordered by ascending. Exception is generated if the array is not correctly ordered. N1 - grid size (number of nodes) in the second dimension, N1>=1 FlagY - array[N0*N1]: * Y[I0+I1*N0] corresponds to node (X0[I0],X1[I1]) * it is a "bitmap" array which contains False for nodes which are NOT calculated, and True for nodes which are required. OUTPUT PARAMETERS: Y - function values, array[NY*N0*N1*N2], where NY is a number of "output" vector values (this function supports vector- valued IDW models): * Y[K+NY*(I0+I1*N0)]=F_k(X0[I0],X1[I1]), for K=0...NY-1, I0=0...N0-1, I1=0...N1-1. * elements of Y[] which correspond to FlagY[]=True are loaded by model values (which may be exactly zero for some nodes). * elements of Y[] which correspond to FlagY[]=False MAY be initialized by zeros OR may be calculated. Generally, they are not calculated, but future SIMD-capable versions may compute several elements in a batch. NOTE: this function supports weakly ordered grid nodes, i.e. you may have X[i]=X[i+1] for some i. It does not provide you any performance benefits due to duplication of points, just convenience and flexibility. NOTE: this function is re-entrant, i.e. you may use same idwmodel structure in multiple threads calling this function for different grids. -- ALGLIB -- Copyright 24.11.2023 by Bochkanov Sergey *************************************************************************/void idwgridcalc2vsubset(const idwmodel &s, const real_1d_array &x0, const ae_int_t n0, const real_1d_array &x1, const ae_int_t n1, const boolean_1d_array &flagy, real_1d_array &y, const xparams _xparams = alglib::xdefault);
idwpeekprogress function/************************************************************************* This function is used to peek into the IDW construction process from some other thread and get the progress indicator. It returns value in [0,1]. IMPORTANT: only MSTAB algorithm supports peeking into progress indicator. Legacy versions of the Shepard's method do not support it. You will always get zero as the result. INPUT PARAMETERS: S - RBF model object RESULT: progress value, in [0,1] -- ALGLIB -- Copyright 27.11.2023 by Bochkanov Sergey *************************************************************************/double idwpeekprogress(const idwbuilder &s, const xparams _xparams = alglib::xdefault);
idwserialize function/************************************************************************* This function serializes data structure to string/stream. 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 a text or XML file. But you should not insert separators into the middle of the "words" nor should you change the 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 it in C# one, and vice versa. *************************************************************************/void idwserialize(const idwmodel &obj, std::string &s_out); void idwserialize(const idwmodel &obj, std::ostream &s_out);
idwtscalcbuf function/************************************************************************* This function calculates values of the IDW model at the given point, using external buffer object (internal temporaries of IDW model are not modified). This function allows to use same IDW model object in different threads, assuming that different threads use different instances of the buffer structure. INPUT PARAMETERS: S - IDW model, may be shared between different threads Buf - buffer object created for this particular instance of IDW model with idwcreatecalcbuffer(). X - coordinates, array[NX]. X may have more than NX elements, in this case only leading NX will be used. Y - possibly preallocated array OUTPUT PARAMETERS: Y - function value, array[NY]. Y is not reallocated when it is larger than NY. -- ALGLIB -- Copyright 13.12.2011 by Bochkanov Sergey *************************************************************************/void idwtscalcbuf(const idwmodel &s, idwcalcbuffer &buf, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
idwunserialize function/************************************************************************* This function unserializes data structure from string/stream. *************************************************************************/void idwunserialize(const std::string &s_in, idwmodel &obj); void idwunserialize(const std::istream &s_in, idwmodel &obj);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example illustrates basic concepts of the IDW models:
// creation and evaluation.
//
// Suppose that we have set of 2-dimensional points with associated
// scalar function values, and we want to build an IDW model using
// our data.
//
// NOTE: we can work with N-dimensional models and vector-valued functions too :)
//
// Typical sequence of steps is given below:
// 1. we create IDW builder object
// 2. we attach our dataset to the IDW builder and tune algorithm settings
// 3. we generate IDW model
// 4. we use IDW model instance (evaluate, serialize, etc.)
//
double v;
//
// Step 1: IDW builder creation.
//
// We have to specify dimensionality of the space (2 or 3) and
// dimensionality of the function (scalar or vector).
//
// New builder object is empty - it has not dataset and uses
// default model construction settings
//
idwbuilder builder;
idwbuildercreate(2, 1, builder);
//
// Step 2: dataset addition
//
// XY contains two points - x0=(-1,0) and x1=(+1,0) -
// and two function values f(x0)=2, f(x1)=3.
//
real_2d_array xy = "[[-1,0,2],[+1,0,3]]";
idwbuildersetpoints(builder, xy);
//
// Step 3: choose IDW algorithm and generate model
//
// We use modified stabilized IDW algorithm with following parameters:
// * SRad - set to 5.0 (search radius must be large enough)
//
// IDW-MSTAB algorithm is a state-of-the-art implementation of IDW which
// is competitive with RBFs and bicubic splines. See comments on the
// idwbuildersetalgomstab() function for more information.
//
idwmodel model;
idwreport rep;
idwbuildersetalgomstab(builder, 5.0);
idwfit(builder, model, rep);
//
// Step 4: model was built, evaluate its value
//
v = idwcalc2(model, 1.0, 0.0);
printf("%.2f\n", double(v)); // EXPECTED: 3.000
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example shows how to serialize and unserialize IDW model.
//
// Suppose that we have set of 2-dimensional points with associated
// scalar function values, and we have built an IDW model using
// our data.
//
// This model can be serialized to string or stream. ALGLIB supports
// flexible (un)serialization, i.e. you can move serialized model
// representation between different machines (32-bit or 64-bit),
// different CPU architectures (x86/64, ARM) or even different
// programming languages supported by ALGLIB (C#, C++, ...).
//
// Our first step is to build model, evaluate it at point (1,0),
// and serialize it to string.
//
std::string s;
double v;
real_2d_array xy = "[[-1,0,2],[+1,0,3]]";
idwbuilder builder;
idwmodel model;
idwmodel model2;
idwreport rep;
idwbuildercreate(2, 1, builder);
idwbuildersetpoints(builder, xy);
idwbuildersetalgomstab(builder, 5.0);
idwfit(builder, model, rep);
v = idwcalc2(model, 1.0, 0.0);
printf("%.2f\n", double(v)); // EXPECTED: 3.000
//
// Serialization + unserialization to a different instance
// of the model class.
//
alglib::idwserialize(model, s);
alglib::idwunserialize(s, model2);
//
// Evaluate unserialized model at the same point
//
v = idwcalc2(model2, 1.0, 0.0);
printf("%.2f\n", double(v)); // EXPECTED: 3.000
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
igammaf subpackageincompletegamma function/************************************************************************* Incomplete gamma integral The function is defined by x - 1 | | -t a-1 igam(a,x) = ----- | e t dt. - | | | (a) - 0 In this implementation both arguments must be positive. The integral is evaluated by either a power series or continued fraction expansion, depending on the relative values of a and x. ACCURACY: Relative error: arithmetic domain # trials peak rms IEEE 0,30 200000 3.6e-14 2.9e-15 IEEE 0,100 300000 9.9e-14 1.5e-14 Cephes Math Library Release 2.8: June, 2000 Copyright 1985, 1987, 2000 by Stephen L. Moshier *************************************************************************/double incompletegamma(const double a, const double x, const xparams _xparams = alglib::xdefault);
incompletegammac function/************************************************************************* Complemented incomplete gamma integral The function is defined by igamc(a,x) = 1 - igam(a,x) inf. - 1 | | -t a-1 = ----- | e t dt. - | | | (a) - x In this implementation both arguments must be positive. The integral is evaluated by either a power series or continued fraction expansion, depending on the relative values of a and x. ACCURACY: Tested at random a, x. a x Relative error: arithmetic domain domain # trials peak rms IEEE 0.5,100 0,100 200000 1.9e-14 1.7e-15 IEEE 0.01,0.5 0,100 200000 1.4e-13 1.6e-15 Cephes Math Library Release 2.8: June, 2000 Copyright 1985, 1987, 2000 by Stephen L. Moshier *************************************************************************/double incompletegammac(const double a, const double x, const xparams _xparams = alglib::xdefault);
invincompletegammac function/************************************************************************* Inverse of complemented imcomplete gamma integral Given p, the function finds x such that igamc( a, x ) = p. Starting with the approximate value 3 x = a t where t = 1 - d - ndtri(p) sqrt(d) and d = 1/9a, the routine performs up to 10 Newton iterations to find the root of igamc(a,x) - p = 0. ACCURACY: Tested at random a, p in the intervals indicated. a p Relative error: arithmetic domain domain # trials peak rms IEEE 0.5,100 0,0.5 100000 1.0e-14 1.7e-15 IEEE 0.01,0.5 0,0.5 100000 9.0e-14 3.4e-15 IEEE 0.5,10000 0,0.5 20000 2.3e-13 3.8e-14 Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier *************************************************************************/double invincompletegammac(const double a, const double y0, const xparams _xparams = alglib::xdefault);
intcomp subpackagensfitspheremcc function/************************************************************************* This function is left for backward compatibility. Use fitspheremc() instead. -- ALGLIB -- Copyright 14.04.2017 by Bochkanov Sergey *************************************************************************/void nsfitspheremcc(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nx, real_1d_array &cx, double &rhi, const xparams _xparams = alglib::xdefault);
nsfitspheremic function/************************************************************************* This function is left for backward compatibility. Use fitspheremi() instead. -- ALGLIB -- Copyright 14.04.2017 by Bochkanov Sergey *************************************************************************/void nsfitspheremic(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nx, real_1d_array &cx, double &rlo, const xparams _xparams = alglib::xdefault);
nsfitspheremzc function/************************************************************************* This function is left for backward compatibility. Use fitspheremz() instead. -- ALGLIB -- Copyright 14.04.2017 by Bochkanov Sergey *************************************************************************/void nsfitspheremzc(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nx, real_1d_array &cx, double &rlo, double &rhi, const xparams _xparams = alglib::xdefault);
nsfitspherex function/************************************************************************* This function is left for backward compatibility. Use fitspherex() instead. -- ALGLIB -- Copyright 14.04.2017 by Bochkanov Sergey *************************************************************************/void nsfitspherex(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nx, const ae_int_t problemtype, const double epsx, const ae_int_t aulits, const double penalty, real_1d_array &cx, double &rlo, double &rhi, const xparams _xparams = alglib::xdefault);
spline1dfitcubic function/************************************************************************* Deprecated fitting function with O(N*M^2+M^3) running time. Superseded by spline1dfit(). -- ALGLIB PROJECT -- Copyright 18.08.2009 by Bochkanov Sergey *************************************************************************/void spline1dfitcubic(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const ae_int_t m, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault); void spline1dfitcubic(const real_1d_array &x, const real_1d_array &y, const ae_int_t m, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault);
spline1dfithermite function/************************************************************************* Deprecated fitting function with O(N*M^2+M^3) running time. Superseded by spline1dfit(). -- ALGLIB PROJECT -- Copyright 18.08.2009 by Bochkanov Sergey *************************************************************************/void spline1dfithermite(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const ae_int_t m, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault); void spline1dfithermite(const real_1d_array &x, const real_1d_array &y, const ae_int_t m, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault);
spline1dfitpenalized function/************************************************************************* This function is an obsolete and deprecated version of fitting by penalized cubic spline. It was superseded by spline1dfit(), which is an orders of magnitude faster and more memory-efficient implementation. Do NOT use this function in the new code! -- ALGLIB PROJECT -- Copyright 18.08.2009 by Bochkanov Sergey *************************************************************************/void spline1dfitpenalized(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const ae_int_t m, const double rho, ae_int_t &info, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault); void spline1dfitpenalized(const real_1d_array &x, const real_1d_array &y, const ae_int_t m, const double rho, ae_int_t &info, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault);
spline1dfitpenalizedw function/************************************************************************* This function is an obsolete and deprecated version of fitting by penalized cubic spline. It was superseded by spline1dfit(), which is an orders of magnitude faster and more memory-efficient implementation. Do NOT use this function in the new code! -- ALGLIB PROJECT -- Copyright 19.10.2010 by Bochkanov Sergey *************************************************************************/void spline1dfitpenalizedw(const real_1d_array &x, const real_1d_array &y, const real_1d_array &w, const ae_int_t n, const ae_int_t m, const double rho, ae_int_t &info, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault); void spline1dfitpenalizedw(const real_1d_array &x, const real_1d_array &y, const real_1d_array &w, const ae_int_t m, const double rho, ae_int_t &info, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault);
inverseupdate subpackagermatrixinvupdatecolumn function/************************************************************************* Inverse matrix update by the Sherman-Morrison formula The algorithm updates matrix A^-1 when adding a vector to a column of matrix A. Input parameters: InvA - inverse of matrix A. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. UpdColumn - the column of A whose vector U was added. 0 <= UpdColumn <= N-1 U - the vector to be added to a column. Array whose index ranges within [0..N-1]. Output parameters: InvA - inverse of modified matrix A. -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/void rmatrixinvupdatecolumn(real_2d_array &inva, const ae_int_t n, const ae_int_t updcolumn, const real_1d_array &u, const xparams _xparams = alglib::xdefault);
rmatrixinvupdaterow function/************************************************************************* Inverse matrix update by the Sherman-Morrison formula The algorithm updates matrix A^-1 when adding a vector to a row of matrix A. Input parameters: InvA - inverse of matrix A. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. UpdRow - the row of A whose vector V was added. 0 <= Row <= N-1 V - the vector to be added to a row. Array whose index ranges within [0..N-1]. Output parameters: InvA - inverse of modified matrix A. -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/void rmatrixinvupdaterow(real_2d_array &inva, const ae_int_t n, const ae_int_t updrow, const real_1d_array &v, const xparams _xparams = alglib::xdefault);
rmatrixinvupdatesimple function/************************************************************************* Inverse matrix update by the Sherman-Morrison formula The algorithm updates matrix A^-1 when adding a number to an element of matrix A. Input parameters: InvA - inverse of matrix A. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. UpdRow - row where the element to be updated is stored. UpdColumn - column where the element to be updated is stored. UpdVal - a number to be added to the element. Output parameters: InvA - inverse of modified matrix A. -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/void rmatrixinvupdatesimple(real_2d_array &inva, const ae_int_t n, const ae_int_t updrow, const ae_int_t updcolumn, const double updval, const xparams _xparams = alglib::xdefault);
rmatrixinvupdateuv function/************************************************************************* Inverse matrix update by the Sherman-Morrison formula The algorithm computes the inverse of matrix A+u*v' by using the given matrix A^-1 and the vectors u and v. Input parameters: InvA - inverse of matrix A. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. U - the vector modifying the matrix. Array whose index ranges within [0..N-1]. V - the vector modifying the matrix. Array whose index ranges within [0..N-1]. Output parameters: InvA - inverse of matrix A + u*v'. -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/void rmatrixinvupdateuv(real_2d_array &inva, const ae_int_t n, const real_1d_array &u, const real_1d_array &v, const xparams _xparams = alglib::xdefault);
iterativesparse subpackagesparsesolverreport class/************************************************************************* This structure is a sparse solver report (both direct and iterative solvers use this structure). Following fields can be accessed by users: * TerminationType (specific error codes depend on the solver being used, with positive values ALWAYS signaling that something useful is returned in X, and negative values ALWAYS meaning critical failures. * NMV - number of matrix-vector products performed (0 for direct solvers) * IterationsCount - inner iterations count (0 for direct solvers) * R2 - squared residual *************************************************************************/class sparsesolverreport { public: sparsesolverreport(); sparsesolverreport(const sparsesolverreport &rhs); sparsesolverreport& operator=(const sparsesolverreport &rhs); virtual ~sparsesolverreport(); ae_int_t terminationtype; ae_int_t nmv; ae_int_t iterationscount; double r2; };
sparsesolverstate class/************************************************************************* This object stores state of the sparse linear solver object. You should use ALGLIB functions to work with this object. Never try to access its fields directly! *************************************************************************/class sparsesolverstate { public: sparsesolverstate(); sparsesolverstate(const sparsesolverstate &rhs); sparsesolverstate& operator=(const sparsesolverstate &rhs); virtual ~sparsesolverstate(); };
sparsesolvegmres function/************************************************************************* Solving sparse linear system A*x=b using GMRES(k) method. This function provides convenience API for an 'expert' interface provided by SparseSolverState class. Use SparseSolver API if you need advanced functions like providing initial point, using out-of-core API and so on. INPUT PARAMETERS: A - sparse NxN matrix in any sparse storage format. Using CRS format is recommended because it avoids internal conversion. An exception will be generated if A is not NxN matrix (where N is a size specified during solver object creation). B - right part, array[N] K - k parameter for GMRES(k), k>=0. Zero value means that algorithm will choose it automatically. EpsF - stopping condition, EpsF>=0. The algorithm will stop when residual will decrease below EpsF*|B|. Having EpsF=0 means that this stopping condition is ignored. MaxIts - stopping condition, MaxIts>=0. The algorithm will stop after performing MaxIts iterations. Zero value means no limit. NOTE: having both EpsF=0 and MaxIts=0 means that stopping criteria will be chosen automatically. OUTPUT PARAMETERS: X - array[N], the solution Rep - solution report: * Rep.TerminationType completion code: * -5 CG method was used for a matrix which is not positive definite * -4 overflow/underflow during solution (ill conditioned problem) * 1 ||residual||<=EpsF*||b|| * 5 MaxIts steps was taken * 7 rounding errors prevent further progress, best point found is returned * 8 the algorithm was terminated early with SparseSolverRequestTermination() being called from other thread. * Rep.IterationsCount contains iterations count * Rep.NMV contains number of matrix-vector calculations * Rep.R2 contains squared residual -- ALGLIB -- Copyright 25.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolvegmres(const sparsematrix &a, const real_1d_array &b, const ae_int_t k, const double epsf, const ae_int_t maxits, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault);
sparsesolvercreate function/************************************************************************* This function initializes sparse linear iterative solver object. This solver can be used to solve nonsymmetric and symmetric positive definite NxN (square) linear systems. The solver provides 'expert' API which allows advanced control over algorithms being used, including ability to get progress report, terminate long-running solver from other thread, out-of-core solution and so on. NOTE: there are also convenience functions that allows quick one-line access to the solvers: * SparseSolveCG() to solve SPD linear systems * SparseSolveGMRES() to solve unsymmetric linear systems. NOTE: if you want to solve MxN (rectangular) linear problem you may use LinLSQR solver provided by ALGLIB. USAGE (A is given by the SparseMatrix structure): 1. User initializes algorithm state with SparseSolverCreate() call 2. User selects algorithm with one of the SparseSolverSetAlgo???() functions. By default, GMRES(k) is used with automatically chosen k 3. Optionally, user tunes solver parameters, sets starting point, etc. 4. Depending on whether system is symmetric or not, user calls: * SparseSolverSolveSymmetric() for a symmetric system given by its lower or upper triangle * SparseSolverSolve() for a nonsymmetric system or a symmetric one given by the full matrix 5. User calls SparseSolverResults() to get the solution It is possible to call SparseSolverSolve???() again to solve another task with same dimensionality but different matrix and/or right part without reinitializing SparseSolverState structure. USAGE (out-of-core mode): 1. User initializes algorithm state with SparseSolverCreate() call 2. User selects algorithm with one of the SparseSolverSetAlgo???() functions. By default, GMRES(k) is used with automatically chosen k 3. Optionally, user tunes solver parameters, sets starting point, etc. 4. After that user should work with out-of-core interface in a loop like one given below: > alglib.sparsesolveroocstart(state) > while alglib.sparsesolverooccontinue(state) do > alglib.sparsesolveroocgetrequestinfo(state, out RequestType) > alglib.sparsesolveroocgetrequestdata(state, out X) > if RequestType=0 then > [calculate Y=A*X, with X=R^N] > alglib.sparsesolveroocsendresult(state, in Y) > alglib.sparsesolveroocstop(state, out X, out Report) INPUT PARAMETERS: N - problem dimensionality (fixed at start-up) OUTPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 24.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolvercreate(const ae_int_t n, sparsesolverstate &state, const xparams _xparams = alglib::xdefault);
sparsesolverooccontinue function/************************************************************************* This function performs iterative solution of the linear system in the out-of-core mode. It should be used in conjunction with other out-of-core- related functions of this subspackage in a loop like one given below: > alglib.sparsesolveroocstart(state) > while alglib.sparsesolverooccontinue(state) do > alglib.sparsesolveroocgetrequestinfo(state, out RequestType) > alglib.sparsesolveroocgetrequestdata(state, out X) > if RequestType=0 then > [calculate Y=A*X, with X=R^N] > alglib.sparsesolveroocsendresult(state, in Y) > alglib.sparsesolveroocstop(state, out X, out Report) -- ALGLIB -- Copyright 24.09.2021 by Bochkanov Sergey *************************************************************************/bool sparsesolverooccontinue(sparsesolverstate &state, const xparams _xparams = alglib::xdefault);
sparsesolveroocgetrequestdata function/************************************************************************* This function is used to retrieve vector associated with out-of-core request sent by the solver to user code. Depending on the request type (returned by the SparseSolverOOCGetRequestInfo()) this vector should be multiplied by A or subjected to another processing. It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like one given below: > alglib.sparsesolveroocstart(state) > while alglib.sparsesolverooccontinue(state) do > alglib.sparsesolveroocgetrequestinfo(state, out RequestType) > alglib.sparsesolveroocgetrequestdata(state, out X) > if RequestType=0 then > [calculate Y=A*X, with X=R^N] > alglib.sparsesolveroocsendresult(state, in Y) > alglib.sparsesolveroocstop(state, out X, out Report) INPUT PARAMETERS: State - solver running in out-of-core mode X - possibly preallocated storage; reallocated if needed, left unchanged, if large enough to store request data. OUTPUT PARAMETERS: X - array[N] or larger, leading N elements are filled with vector X. -- ALGLIB -- Copyright 24.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolveroocgetrequestdata(sparsesolverstate &state, real_1d_array &x, const xparams _xparams = alglib::xdefault);
sparsesolveroocgetrequestdata1 function/************************************************************************* This function is used to retrieve scalar value associated with out-of-core request sent by the solver to user code. In the current ALGLIB version this function is used to retrieve squared residual norm during progress reports. INPUT PARAMETERS: State - solver running in out-of-core mode OUTPUT PARAMETERS: V - scalar value associated with the current request -- ALGLIB -- Copyright 24.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolveroocgetrequestdata1(sparsesolverstate &state, double &v, const xparams _xparams = alglib::xdefault);
sparsesolveroocgetrequestinfo function/************************************************************************* This function is used to retrieve information about out-of-core request sent by the solver: * RequestType=0 means that matrix-vector products A*x is requested * RequestType=-1 means that solver reports its progress; this request is returned only when reports are activated wit SparseSolverSetXRep(). This function returns just request type; in order to get contents of the trial vector, use sparsesolveroocgetrequestdata(). It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like one given below: > alglib.sparsesolveroocstart(state) > while alglib.sparsesolverooccontinue(state) do > alglib.sparsesolveroocgetrequestinfo(state, out RequestType) > alglib.sparsesolveroocgetrequestdata(state, out X) > if RequestType=0 then > [calculate Y=A*X, with X=R^N] > alglib.sparsesolveroocsendresult(state, in Y) > alglib.sparsesolveroocstop(state, out X, out Report) INPUT PARAMETERS: State - solver running in out-of-core mode OUTPUT PARAMETERS: RequestType - type of the request to process: * 0 for matrix-vector product A*x, with A being NxN system matrix and X being N-dimensional vector *-1 for location and residual report -- ALGLIB -- Copyright 24.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolveroocgetrequestinfo(sparsesolverstate &state, ae_int_t &requesttype, const xparams _xparams = alglib::xdefault);
sparsesolveroocsendresult function/************************************************************************* This function is used to send user reply to out-of-core request sent by the solver. Usually it is product A*x for vector X returned by the solver. It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like one given below: > alglib.sparsesolveroocstart(state) > while alglib.sparsesolverooccontinue(state) do > alglib.sparsesolveroocgetrequestinfo(state, out RequestType) > alglib.sparsesolveroocgetrequestdata(state, out X) > if RequestType=0 then > [calculate Y=A*X, with X=R^N] > alglib.sparsesolveroocsendresult(state, in Y) > alglib.sparsesolveroocstop(state, out X, out Report) INPUT PARAMETERS: State - solver running in out-of-core mode AX - array[N] or larger, leading N elements contain A*x -- ALGLIB -- Copyright 24.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolveroocsendresult(sparsesolverstate &state, const real_1d_array &ax, const xparams _xparams = alglib::xdefault);
sparsesolveroocstart function/************************************************************************* This function initiates out-of-core mode of the sparse solver. It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like one given below: > alglib.sparsesolveroocstart(state) > while alglib.sparsesolverooccontinue(state) do > alglib.sparsesolveroocgetrequestinfo(state, out RequestType) > alglib.sparsesolveroocgetrequestdata(state, out X) > if RequestType=0 then > [calculate Y=A*X, with X=R^N] > alglib.sparsesolveroocsendresult(state, in Y) > alglib.sparsesolveroocstop(state, out X, out Report) INPUT PARAMETERS: State - solver object -- ALGLIB -- Copyright 24.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolveroocstart(sparsesolverstate &state, const real_1d_array &b, const xparams _xparams = alglib::xdefault);
sparsesolveroocstop function/************************************************************************* This function finalizes out-of-core mode of the linear solver. It should be used in conjunction with other out-of-core-related functions of this subspackage in a loop like one given below: > alglib.sparsesolveroocstart(state) > while alglib.sparsesolverooccontinue(state) do > alglib.sparsesolveroocgetrequestinfo(state, out RequestType) > alglib.sparsesolveroocgetrequestdata(state, out X) > if RequestType=0 then > [calculate Y=A*X, with X=R^N] > alglib.sparsesolveroocsendresult(state, in Y) > alglib.sparsesolveroocstop(state, out X, out Report) INPUT PARAMETERS: State - solver state OUTPUT PARAMETERS: X - array[N], the solution. Zero-filled on the failure (Rep.TerminationType<0). Rep - report with additional info: * Rep.TerminationType completion code: * -5 CG method was used for a matrix which is not positive definite * -4 overflow/underflow during solution (ill conditioned problem) * 1 ||residual||<=EpsF*||b|| * 5 MaxIts steps was taken * 7 rounding errors prevent further progress, best point found is returned * 8 the algorithm was terminated early with SparseSolverRequestTermination() being called from other thread. * Rep.IterationsCount contains iterations count * Rep.NMV contains number of matrix-vector calculations * Rep.R2 contains squared residual -- ALGLIB -- Copyright 24.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolveroocstop(sparsesolverstate &state, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault);
sparsesolverrequesttermination function/************************************************************************* This subroutine submits request for termination of the running solver. It can be called from some other thread which wants the solver to terminate or when processing an out-of-core request. As result, solver stops at point which was "current accepted" when the termination request was submitted and returns error code 8 (successful termination). Such termination is a smooth process which properly deallocates all temporaries. INPUT PARAMETERS: State - solver structure NOTE: calling this function on solver which is NOT running will have no effect. NOTE: multiple calls to this function are possible. First call is counted, subsequent calls are silently ignored. NOTE: solver clears termination flag on its start, it means that if some other thread will request termination too soon, its request will went unnoticed. -- ALGLIB -- Copyright 01.10.2021 by Bochkanov Sergey *************************************************************************/void sparsesolverrequesttermination(sparsesolverstate &state, const xparams _xparams = alglib::xdefault);
sparsesolverresults function/************************************************************************* Sparse solver results. This function must be called after calling one of the SparseSolverSolve() functions. INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: X - array[N], solution Rep - solution report: * Rep.TerminationType completion code: * -5 CG method was used for a matrix which is not positive definite * -4 overflow/underflow during solution (ill conditioned problem) * 1 ||residual||<=EpsF*||b|| * 5 MaxIts steps was taken * 7 rounding errors prevent further progress, best point found is returned * 8 the algorithm was terminated early with SparseSolverRequestTermination() being called from other thread. * Rep.IterationsCount contains iterations count * Rep.NMV contains number of matrix-vector calculations * Rep.R2 contains squared residual s -- ALGLIB -- Copyright 14.11.2011 by Bochkanov Sergey *************************************************************************/void sparsesolverresults(sparsesolverstate &state, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault);
sparsesolversetalgogmres function/************************************************************************* This function sets the solver algorithm to GMRES(k). NOTE: if you do not need advanced functionality of the SparseSolver API, you may use convenience functions SparseSolveGMRES() and SparseSolveSymmetricGMRES(). INPUT PARAMETERS: State - structure which stores algorithm state K - GMRES parameter, K>=0: * recommended values are in 10..100 range * larger values up to N are possible but have little sense - the algorithm will be slower than any dense solver. * values above N are truncated down to N * zero value means that default value is chosen. This value is 50 in the current version, but it may change in future ALGLIB releases. -- ALGLIB -- Copyright 24.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolversetalgogmres(sparsesolverstate &state, const ae_int_t k, const xparams _xparams = alglib::xdefault);
sparsesolversetcond function/************************************************************************* This function sets stopping criteria. INPUT PARAMETERS: EpsF - algorithm will be stopped if norm of residual is less than EpsF*||b||. MaxIts - algorithm will be stopped if number of iterations is more than MaxIts. OUTPUT PARAMETERS: State - structure which stores algorithm state NOTES: If both EpsF and MaxIts are zero then small EpsF will be set to small value. -- ALGLIB -- Copyright 14.11.2011 by Bochkanov Sergey *************************************************************************/void sparsesolversetcond(sparsesolverstate &state, const double epsf, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
sparsesolversetstartingpoint function/************************************************************************* This function sets starting point. By default, zero starting point is used. INPUT PARAMETERS: State - structure which stores algorithm state X - starting point, array[N] OUTPUT PARAMETERS: State - new starting point was set -- ALGLIB -- Copyright 24.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolversetstartingpoint(sparsesolverstate &state, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
sparsesolversetxrep function/************************************************************************* This function turns on/off reporting during out-of-core processing. When the solver works in the out-of-core mode, it can be configured to report its progress by returning current location. These location reports are implemented as a special kind of the out-of-core request: * SparseSolverOOCGetRequestInfo() returns -1 * SparseSolverOOCGetRequestData() returns current location * SparseSolverOOCGetRequestData1() returns squared norm of the residual * SparseSolverOOCSendResult() shall NOT be called This function has no effect when SparseSolverSolve() is used because this function has no method of reporting its progress. NOTE: when used with GMRES(k), this function reports progress every k-th iteration. INPUT PARAMETERS: State - structure which stores algorithm state NeedXRep- whether iteration reports are needed or not -- ALGLIB -- Copyright 01.10.2021 by Bochkanov Sergey *************************************************************************/void sparsesolversetxrep(sparsesolverstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
sparsesolversolve function/************************************************************************* Procedure for the solution of A*x=b with sparse nonsymmetric A IMPORTANT: this function will work with any solver algorithm being used, symmetric solver like CG, or not. However, using symmetric solvers on nonsymmetric problems is dangerous. It may solve the problem up to desired precision (sometimes, rarely) or terminate with error code signalling violation of underlying assumptions. INPUT PARAMETERS: State - algorithm state A - sparse NxN matrix in any sparse storage format. Using CRS format is recommended because it avoids internal conversion. An exception will be generated if A is not NxN matrix (where N is a size specified during solver object creation). B - right part, array[N] RESULT: This function returns no result. You can get the solution by calling SparseSolverResults() -- ALGLIB -- Copyright 25.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolversolve(sparsesolverstate &state, const sparsematrix &a, const real_1d_array &b, const xparams _xparams = alglib::xdefault);
sparsesolversolvesymmetric function/************************************************************************* Procedure for the solution of A*x=b with sparse symmetric A given by its lower or upper triangle. This function will work with any solver algorithm being used, SPD one (like CG) or not (like GMRES). Using unsymmetric solvers (like GMRES) on SPD problems is suboptimal, but still possible. NOTE: the solver behavior is ill-defined for a situation when a SPD solver is used on indefinite matrix. It may solve the problem up to desired precision (sometimes, rarely) or return with error code signalling violation of underlying assumptions. INPUT PARAMETERS: State - algorithm state A - sparse symmetric NxN matrix in any sparse storage format. Using CRS format is recommended because it avoids internal conversion. An exception will be generated if A is not NxN matrix (where N is a size specified during solver object creation). IsUpper - whether upper or lower triangle of A is used: * IsUpper=True => only upper triangle is used and lower triangle is not referenced at all * IsUpper=False => only lower triangle is used and upper triangle is not referenced at all B - right part, array[N] RESULT: This function returns no result. You can get the solution by calling SparseSolverResults() -- ALGLIB -- Copyright 25.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolversolvesymmetric(sparsesolverstate &state, const sparsematrix &a, const bool isupper, const real_1d_array &b, const xparams _xparams = alglib::xdefault);
sparsesolvesymmetricgmres function/************************************************************************* Solving sparse symmetric linear system A*x=b using GMRES(k) method. Sparse symmetric A is given by its lower or upper triangle. NOTE: use SparseSolveGMRES() to solve system with nonsymmetric A. This function provides convenience API for an 'expert' interface provided by SparseSolverState class. Use SparseSolver API if you need advanced functions like providing initial point, using out-of-core API and so on. INPUT PARAMETERS: A - sparse symmetric NxN matrix in any sparse storage format. Using CRS format is recommended because it avoids internal conversion. An exception will be generated if A is not NxN matrix (where N is a size specified during solver object creation). IsUpper - whether upper or lower triangle of A is used: * IsUpper=True => only upper triangle is used and lower triangle is not referenced at all * IsUpper=False => only lower triangle is used and upper triangle is not referenced at all B - right part, array[N] K - k parameter for GMRES(k), k>=0. Zero value means that algorithm will choose it automatically. EpsF - stopping condition, EpsF>=0. The algorithm will stop when residual will decrease below EpsF*|B|. Having EpsF=0 means that this stopping condition is ignored. MaxIts - stopping condition, MaxIts>=0. The algorithm will stop after performing MaxIts iterations. Zero value means no limit. NOTE: having both EpsF=0 and MaxIts=0 means that stopping criteria will be chosen automatically. OUTPUT PARAMETERS: X - array[N], the solution Rep - solution report: * Rep.TerminationType completion code: * -5 CG method was used for a matrix which is not positive definite * -4 overflow/underflow during solution (ill conditioned problem) * 1 ||residual||<=EpsF*||b|| * 5 MaxIts steps was taken * 7 rounding errors prevent further progress, best point found is returned * 8 the algorithm was terminated early with SparseSolverRequestTermination() being called from other thread. * Rep.IterationsCount contains iterations count * Rep.NMV contains number of matrix-vector calculations * Rep.R2 contains squared residual -- ALGLIB -- Copyright 25.09.2021 by Bochkanov Sergey *************************************************************************/void sparsesolvesymmetricgmres(const sparsematrix &a, const bool isupper, const real_1d_array &b, const ae_int_t k, const double epsf, const ae_int_t maxits, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams = alglib::xdefault);
jacobianelliptic subpackagejacobianellipticfunctions function/************************************************************************* Jacobian Elliptic Functions Evaluates the Jacobian elliptic functions sn(u|m), cn(u|m), and dn(u|m) of parameter m between 0 and 1, and real argument u. These functions are periodic, with quarter-period on the real axis equal to the complete elliptic integral ellpk(1.0-m). Relation to incomplete elliptic integral: If u = ellik(phi,m), then sn(u|m) = sin(phi), and cn(u|m) = cos(phi). Phi is called the amplitude of u. Computation is by means of the arithmetic-geometric mean algorithm, except when m is within 1e-9 of 0 or 1. In the latter case with m close to 1, the approximation applies only for phi < pi/2. ACCURACY: Tested at random points with u between 0 and 10, m between 0 and 1. Absolute error (* = relative error): arithmetic function # trials peak rms IEEE phi 10000 9.2e-16* 1.4e-16* IEEE sn 50000 4.1e-15 4.6e-16 IEEE cn 40000 3.6e-15 4.4e-16 IEEE dn 10000 1.3e-12 1.8e-14 Peak error observed in consistency check using addition theorem for sn(u+v) was 4e-16 (absolute). Also tested by the above relation to the incomplete elliptic integral. Accuracy deteriorates when u is large. Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier *************************************************************************/void jacobianellipticfunctions(const double u, const double m, double &sn, double &cn, double &dn, double &ph, const xparams _xparams = alglib::xdefault);
jarquebera subpackagejarqueberatest function/************************************************************************* Jarque-Bera test This test checks hypotheses about the fact that a given sample X is a sample of normal random variable. Requirements: * the number of elements in the sample is not less than 5. Input parameters: X - sample. Array whose index goes from 0 to N-1. N - size of the sample. N>=5 Output parameters: P - p-value for the test Accuracy of the approximation used (5<=N<=1951): p-value relative error (5<=N<=1951) [1, 0.1] < 1% [0.1, 0.01] < 2% [0.01, 0.001] < 6% [0.001, 0] wasn't measured For N>1951 accuracy wasn't measured but it shouldn't be sharply different from table values. -- ALGLIB -- Copyright 09.04.2007 by Bochkanov Sergey *************************************************************************/void jarqueberatest(const real_1d_array &x, const ae_int_t n, double &p, const xparams _xparams = alglib::xdefault);
knn subpackage| knn_cls | Simple classification with KNN model | |
| knn_reg | Simple classification with KNN model |
knnbuffer class/************************************************************************* Buffer object which is used to perform various requests (usually model inference) in the multithreaded mode (multiple threads working with same KNN object). This object should be created with KNNCreateBuffer(). *************************************************************************/class knnbuffer { public: knnbuffer(); knnbuffer(const knnbuffer &rhs); knnbuffer& operator=(const knnbuffer &rhs); virtual ~knnbuffer(); };
knnbuilder class/************************************************************************* A KNN builder object; this object encapsulates dataset and all related settings, it is used to create an actual instance of KNN model. *************************************************************************/class knnbuilder { public: knnbuilder(); knnbuilder(const knnbuilder &rhs); knnbuilder& operator=(const knnbuilder &rhs); virtual ~knnbuilder(); };
knnmodel class/************************************************************************* KNN model, can be used for classification or regression *************************************************************************/class knnmodel { public: knnmodel(); knnmodel(const knnmodel &rhs); knnmodel& operator=(const knnmodel &rhs); virtual ~knnmodel(); };
knnreport class/************************************************************************* KNN training report. Following fields store training set errors: * relclserror - fraction of misclassified cases, [0,1] * avgce - average cross-entropy in bits per symbol * rmserror - root-mean-square error * avgerror - average error * avgrelerror - average relative error For classification problems: * RMS, AVG and AVGREL errors are calculated for posterior probabilities For regression problems: * RELCLS and AVGCE errors are zero *************************************************************************/class knnreport { public: knnreport(); knnreport(const knnreport &rhs); knnreport& operator=(const knnreport &rhs); virtual ~knnreport(); double relclserror; double avgce; double rmserror; double avgerror; double avgrelerror; };
knnallerrors function/************************************************************************* Calculates all kinds of errors for the model in one call. INPUT PARAMETERS: Model - KNN model XY - test set: * one row per point * first NVars columns store independent variables * depending on problem type: * next column stores class number in [0,NClasses) - for classification problems * next NOut columns store dependent variables - for regression problems NPoints - test set size, NPoints>=0 OUTPUT PARAMETERS: Rep - following fields are loaded with errors for both regression and classification models: * rep.rmserror - RMS error for the output * rep.avgerror - average error * rep.avgrelerror - average relative error following fields are set only for classification models, zero for regression ones: * relclserror - relative classification error, in [0,1] * avgce - average cross-entropy in bits per dataset entry NOTE: the cross-entropy metric is too unstable when used to evaluate KNN models (such models can report exactly zero probabilities), so we do not recommend using it. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knnallerrors(const knnmodel &model, const real_2d_array &xy, const ae_int_t npoints, knnreport &rep, const xparams _xparams = alglib::xdefault);
knnavgce function/************************************************************************* Average cross-entropy (in bits per element) on the test set INPUT PARAMETERS: Model - KNN model XY - test set NPoints - test set size RESULT: CrossEntropy/NPoints. Zero if model solves regression task. NOTE: the cross-entropy metric is too unstable when used to evaluate KNN models (such models can report exactly zero probabilities), so we do not recommend using it. NOTE: if you need several different kinds of error metrics, it is better to use knnallerrors() which computes all error metric with just one pass over dataset. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/double knnavgce(const knnmodel &model, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
knnavgerror function/************************************************************************* Average error on the test set Its meaning for regression task is obvious. As for classification problems, average error means error when estimating posterior probabilities. INPUT PARAMETERS: Model - KNN model XY - test set NPoints - test set size RESULT: average error NOTE: if you need several different kinds of error metrics, it is better to use knnallerrors() which computes all error metric with just one pass over dataset. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/double knnavgerror(const knnmodel &model, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
knnavgrelerror function/************************************************************************* Average relative error on the test set Its meaning for regression task is obvious. As for classification problems, average relative error means error when estimating posterior probabilities. INPUT PARAMETERS: Model - KNN model XY - test set NPoints - test set size RESULT: average relative error NOTE: if you need several different kinds of error metrics, it is better to use knnallerrors() which computes all error metric with just one pass over dataset. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/double knnavgrelerror(const knnmodel &model, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
knnbuilderbuildknnmodel function/************************************************************************* This subroutine builds KNN model according to current settings, using dataset internally stored in the builder object. The model being built performs inference using Eps-approximate K nearest neighbors search algorithm, with: * K=1, Eps=0 corresponding to the "nearest neighbor algorithm" * K>1, Eps=0 corresponding to the "K nearest neighbors algorithm" * K>=1, Eps>0 corresponding to "approximate nearest neighbors algorithm" An approximate KNN is a good option for high-dimensional datasets (exact KNN works slowly when dimensions count grows). An ALGLIB implementation of kd-trees is used to perform k-nn searches. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. INPUT PARAMETERS: S - KNN builder object K - number of neighbors to search for, K>=1 Eps - approximation factor: * Eps=0 means that exact kNN search is performed * Eps>0 means that (1+Eps)-approximate search is performed OUTPUT PARAMETERS: Model - KNN model Rep - report -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knnbuilderbuildknnmodel(knnbuilder &s, const ae_int_t k, const double eps, knnmodel &model, knnreport &rep, const xparams _xparams = alglib::xdefault);
knnbuildercreate function/************************************************************************* This subroutine creates KNNBuilder object which is used to train KNN models. By default, new builder stores empty dataset and some reasonable default settings. At the very least, you should specify dataset prior to building KNN model. You can also tweak settings of the model construction algorithm (recommended, although default settings should work well). Following actions are mandatory: * calling knnbuildersetdataset() to specify dataset * calling knnbuilderbuildknnmodel() to build KNN model using current dataset and default settings Additionally, you may call: * knnbuildersetnorm() to change norm being used INPUT PARAMETERS: none OUTPUT PARAMETERS: S - KNN builder -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knnbuildercreate(knnbuilder &s, const xparams _xparams = alglib::xdefault);
knnbuildersetdatasetcls function/************************************************************************* Specifies classification problem (two or more classes are predicted). There also exists "regression" version of this function. This subroutine adds dense dataset to the internal storage of the builder object. Specifying your dataset in the dense format means that the dense version of the KNN construction algorithm will be invoked. INPUT PARAMETERS: S - KNN builder object XY - array[NPoints,NVars+1] (note: actual size can be larger, only leading part is used anyway), dataset: * first NVars elements of each row store values of the independent variables * next element stores class index, in [0,NClasses) NPoints - number of rows in the dataset, NPoints>=1 NVars - number of independent variables, NVars>=1 NClasses - number of classes, NClasses>=2 OUTPUT PARAMETERS: S - KNN builder -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knnbuildersetdatasetcls(knnbuilder &s, const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, const xparams _xparams = alglib::xdefault);
Examples: [1]
knnbuildersetdatasetreg function/************************************************************************* Specifies regression problem (one or more continuous output variables are predicted). There also exists "classification" version of this function. This subroutine adds dense dataset to the internal storage of the builder object. Specifying your dataset in the dense format means that the dense version of the KNN construction algorithm will be invoked. INPUT PARAMETERS: S - KNN builder object XY - array[NPoints,NVars+NOut] (note: actual size can be larger, only leading part is used anyway), dataset: * first NVars elements of each row store values of the independent variables * next NOut elements store values of the dependent variables NPoints - number of rows in the dataset, NPoints>=1 NVars - number of independent variables, NVars>=1 NOut - number of dependent variables, NOut>=1 OUTPUT PARAMETERS: S - KNN builder -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knnbuildersetdatasetreg(knnbuilder &s, const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nout, const xparams _xparams = alglib::xdefault);
Examples: [1]
knnbuildersetnorm function/************************************************************************* This function sets norm type used for neighbor search. INPUT PARAMETERS: S - decision forest builder object NormType - norm type: * 0 inf-norm * 1 1-norm * 2 Euclidean norm (default) OUTPUT PARAMETERS: S - decision forest builder -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knnbuildersetnorm(knnbuilder &s, const ae_int_t nrmtype, const xparams _xparams = alglib::xdefault);
knnclassify function/************************************************************************* This function returns most probable class number for an input X. It is same as calling knnprocess(model,x,y), then determining i=argmax(y[i]) and returning i. A class number in [0,NOut) range in returned for classification problems, -1 is returned when this function is called for regression problems. IMPORTANT: this function is thread-unsafe and modifies internal structures of the model! You can not use same model object for parallel evaluation from several threads. Use knntsprocess() with independent thread-local buffers, if you need thread-safe evaluation. INPUT PARAMETERS: Model - KNN model X - input vector, array[0..NVars-1]. RESULT: class number, -1 for regression tasks -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/ae_int_t knnclassify(knnmodel &model, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
knncreatebuffer function/************************************************************************* This function creates buffer structure which can be used to perform parallel KNN requests. KNN subpackage provides two sets of computing functions - ones which use internal buffer of KNN model (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 Model - KNN model which is associated with newly created buffer OUTPUT PARAMETERS Buf - external buffer. IMPORTANT: buffer object should be used only with model 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 the model structure. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knncreatebuffer(const knnmodel &model, knnbuffer &buf, const xparams _xparams = alglib::xdefault);
knnprocess function/************************************************************************* Inference using KNN model. See also knnprocess0(), knnprocessi() and knnclassify() for options with a bit more convenient interface. IMPORTANT: this function is thread-unsafe and modifies internal structures of the model! You can not use same model object for parallel evaluation from several threads. Use knntsprocess() with independent thread-local buffers, if you need thread-safe evaluation. INPUT PARAMETERS: Model - KNN model X - input vector, array[0..NVars-1]. Y - possible preallocated buffer. Reused if long enough. OUTPUT PARAMETERS: Y - result. Regression estimate when solving regression task, vector of posterior probabilities for classification task. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knnprocess(knnmodel &model, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
knnprocess0 function/************************************************************************* This function returns first component of the inferred vector (i.e. one with index #0). It is a convenience wrapper for knnprocess() intended for either: * 1-dimensional regression problems * 2-class classification problems In the former case this function returns inference result as scalar, which is definitely more convenient that wrapping it as vector. In the latter case it returns probability of object belonging to class #0. If you call it for anything different from two cases above, it will work as defined, i.e. return y[0], although it is of less use in such cases. IMPORTANT: this function is thread-unsafe and modifies internal structures of the model! You can not use same model object for parallel evaluation from several threads. Use knntsprocess() with independent thread-local buffers, if you need thread-safe evaluation. INPUT PARAMETERS: Model - KNN model X - input vector, array[0..NVars-1]. RESULT: Y[0] -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/double knnprocess0(knnmodel &model, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
knnprocessi function/************************************************************************* 'interactive' variant of knnprocess() for languages like Python which support constructs like "y = knnprocessi(model,x)" and interactive mode of the 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. IMPORTANT: this function is thread-unsafe and may modify internal structures of the model! You can not use same model object for parallel evaluation from several threads. Use knntsprocess() with independent thread-local buffers if you need thread-safe evaluation. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knnprocessi(knnmodel &model, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
knnrelclserror function/************************************************************************* Relative classification error on the test set INPUT PARAMETERS: Model - KNN model XY - test set NPoints - test set size RESULT: percent of incorrectly classified cases. Zero if model solves regression task. NOTE: if you need several different kinds of error metrics, it is better to use knnallerrors() which computes all error metric with just one pass over dataset. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/double knnrelclserror(const knnmodel &model, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
knnrewritekeps function/************************************************************************* Changing search settings of KNN model. K and EPS parameters of KNN (AKNN) search are specified during model construction. However, plain KNN algorithm with Euclidean distance allows you to change them at any moment. NOTE: future versions of KNN model may support advanced versions of KNN, such as NCA or LMNN. It is possible that such algorithms won't allow you to change search settings on the fly. If you call this function for an algorithm which does not support on-the-fly changes, it will throw an exception. INPUT PARAMETERS: Model - KNN model K - K>=1, neighbors count EPS - accuracy of the EPS-approximate NN search. Set to 0.0, if you want to perform "classic" KNN search. Specify larger values if you need to speed-up high-dimensional KNN queries. OUTPUT PARAMETERS: nothing on success, exception on failure -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knnrewritekeps(knnmodel &model, const ae_int_t k, const double eps, const xparams _xparams = alglib::xdefault);
knnrmserror function/************************************************************************* RMS error on the test set. Its meaning for regression task is obvious. As for classification problems, RMS error means error when estimating posterior probabilities. INPUT PARAMETERS: Model - KNN model XY - test set NPoints - test set size RESULT: root mean square error. NOTE: if you need several different kinds of error metrics, it is better to use knnallerrors() which computes all error metric with just one pass over dataset. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/double knnrmserror(const knnmodel &model, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
knnserialize function/************************************************************************* This function serializes data structure to string/stream. 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 a text or XML file. But you should not insert separators into the middle of the "words" nor should you change the 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 it in C# one, and vice versa. *************************************************************************/void knnserialize(const knnmodel &obj, std::string &s_out); void knnserialize(const knnmodel &obj, std::ostream &s_out);
knntsprocess function/************************************************************************* Thread-safe procesing using external buffer for temporaries. This function is thread-safe (i.e . you can use same KNN model from multiple threads) as long as you use different buffer objects for different threads. INPUT PARAMETERS: Model - KNN model Buf - buffer object, must be allocated specifically for this model with knncreatebuffer(). X - input vector, array[NVars] OUTPUT PARAMETERS: Y - result, array[NOut]. Regression estimate when solving regression task, vector of posterior probabilities for a classification task. -- ALGLIB -- Copyright 15.02.2019 by Bochkanov Sergey *************************************************************************/void knntsprocess(const knnmodel &model, knnbuffer &buf, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
knnunserialize function/************************************************************************* This function unserializes data structure from string/stream. *************************************************************************/void knnunserialize(const std::string &s_in, knnmodel &obj); void knnunserialize(const std::istream &s_in, knnmodel &obj);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// The very simple classification example: classify points (x,y) in 2D space
// as ones with x>=0 and ones with x<0 (y is ignored, but our classifier
// has to find out it).
//
// First, we have to create KNN builder object, load dataset and specify
// training settings. Our dataset is specified as matrix, which has following
// format:
//
// x0 y0 class0
// x1 y1 class1
// x2 y2 class2
// ....
//
// Here xi and yi can be any values (and in fact you can have any number of
// independent variables), and classi MUST be integer number in [0,NClasses)
// range. In our example we denote points with x>=0 as class #0, and
// ones with negative xi as class #1.
//
// NOTE: if you want to solve regression problem, specify dataset in similar
// format, but with dependent variable(s) instead of class labels. You
// can have dataset with multiple dependent variables, by the way!
//
// For the sake of simplicity, our example includes only 4-point dataset and
// really simple K=1 nearest neighbor search. Industrial problems typically
// need larger values of K.
//
knnbuilder builder;
ae_int_t nvars = 2;
ae_int_t nclasses = 2;
ae_int_t npoints = 4;
real_2d_array xy = "[[1,1,0],[1,-1,0],[-1,1,1],[-1,-1,1]]";
knnbuildercreate(builder);
knnbuildersetdatasetcls(builder, xy, npoints, nvars, nclasses);
// we build KNN model with k=1 and eps=0 (exact k-nn search is performed)
ae_int_t k = 1;
double eps = 0;
knnmodel model;
knnreport rep;
knnbuilderbuildknnmodel(builder, k, eps, model, rep);
// with such settings (k=1 is used) you can expect zero classification
// error on training set. Beautiful results, but remember - in real life
// you do not need zero TRAINING SET error, you need good generalization.
printf("%.4f\n", double(rep.relclserror)); // EXPECTED: 0.0000
// now, let's perform some simple processing with knnprocess()
real_1d_array x = "[+1,0]";
real_1d_array y = "[]";
knnprocess(model, x, y);
printf("%s\n", y.tostring(3).c_str()); // EXPECTED: [+1,0]
// another option is to use knnprocess0() which returns just first component
// of the output vector y. ideal for regression problems and binary classifiers.
double y0;
y0 = knnprocess0(model, x);
printf("%.3f\n", double(y0)); // EXPECTED: 1.000
// finally, you can use knnclassify() which returns most probable class index (i.e. argmax y[i]).
ae_int_t i;
i = knnclassify(model, x);
printf("%d\n", int(i)); // EXPECTED: 0
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// The very simple regression example: model f(x,y)=x+y
//
// First, we have to create KNN builder object, load dataset and specify
// training settings. Our dataset is specified as matrix, which has following
// format:
//
// x0 y0 f0
// x1 y1 f1
// x2 y2 f2
// ....
//
// Here xi and yi can be any values, and fi is a dependent function value.
// By the way, with KNN algorithm you can even model functions with multiple
// dependent variables!
//
// NOTE: you can also solve classification problems with KNN models, see
// another example for this unit.
//
// For the sake of simplicity, our example includes only 4-point dataset and
// really simple K=1 nearest neighbor search. Industrial problems typically
// need larger values of K.
//
knnbuilder builder;
ae_int_t nvars = 2;
ae_int_t nout = 1;
ae_int_t npoints = 4;
real_2d_array xy = "[[1,1,+2],[1,-1,0],[-1,1,0],[-1,-1,-2]]";
knnbuildercreate(builder);
knnbuildersetdatasetreg(builder, xy, npoints, nvars, nout);
// we build KNN model with k=1 and eps=0 (exact k-nn search is performed)
ae_int_t k = 1;
double eps = 0;
knnmodel model;
knnreport rep;
knnbuilderbuildknnmodel(builder, k, eps, model, rep);
// with such settings (k=1 is used) you can expect zero RMS error on the
// training set. Beautiful results, but remember - in real life you do not
// need zero TRAINING SET error, you need good generalization.
printf("%.4f\n", double(rep.rmserror)); // EXPECTED: 0.0000
// now, let's perform some simple processing with knnprocess()
real_1d_array x = "[+1,+1]";
real_1d_array y = "[]";
knnprocess(model, x, y);
printf("%s\n", y.tostring(3).c_str()); // EXPECTED: [+2]
// another option is to use knnprocess0() which returns just first component
// of the output vector y. ideal for regression problems and binary classifiers.
double y0;
y0 = knnprocess0(model, x);
printf("%.3f\n", double(y0)); // EXPECTED: 2.000
// there also exist another convenience function, knnclassify(),
// but it does not work for regression problems - it always returns -1.
ae_int_t i;
i = knnclassify(model, x);
printf("%d\n", int(i)); // EXPECTED: -1
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
laguerre subpackagelaguerrecalculate function/************************************************************************* Calculation of the value of the Laguerre polynomial. Parameters: n - degree, n>=0 x - argument Result: the value of the Laguerre polynomial Ln at x *************************************************************************/double laguerrecalculate(const ae_int_t n, const double x, const xparams _xparams = alglib::xdefault);
laguerrecoefficients function/************************************************************************* Representation of Ln as C[0] + C[1]*X + ... + C[N]*X^N Input parameters: N - polynomial degree, n>=0 Output parameters: C - coefficients *************************************************************************/void laguerrecoefficients(const ae_int_t n, real_1d_array &c, const xparams _xparams = alglib::xdefault);
laguerresum function/************************************************************************* Summation of Laguerre polynomials using Clenshaw's recurrence formula. This routine calculates c[0]*L0(x) + c[1]*L1(x) + ... + c[N]*LN(x) Parameters: n - degree, n>=0 x - argument Result: the value of the Laguerre polynomial at x *************************************************************************/double laguerresum(const real_1d_array &c, const ae_int_t n, const double x, const xparams _xparams = alglib::xdefault);
lda subpackagefisherlda function/************************************************************************* Multiclass Fisher LDA The function finds coefficients of a linear combination which optimally separates training set. Most suited for 2-class problems, see fisherldan() for an variant that returns N-dimensional basis. INPUT PARAMETERS: XY - training set, array[NPoints,NVars+1]. First NVars columns store values of independent variables, the next column stores class index (from 0 to NClasses-1) which dataset element belongs to. Fractional values are rounded to the nearest integer. The class index must be in the [0,NClasses-1] range, an exception is generated otherwise. NPoints - training set size, NPoints>=0 NVars - number of independent variables, NVars>=1 NClasses - number of classes, NClasses>=2 OUTPUT PARAMETERS: W - linear combination coefficients, array[NVars] ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 31.05.2008 by Bochkanov Sergey *************************************************************************/void fisherlda(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, real_1d_array &w, const xparams _xparams = alglib::xdefault); void fisherlda(const real_2d_array &xy, const ae_int_t nclasses, real_1d_array &w, const xparams _xparams = alglib::xdefault);
fisherldan function/************************************************************************* N-dimensional multiclass Fisher LDA Subroutine finds coefficients of linear combinations which optimally separates training set on classes. It returns N-dimensional basis whose vector are sorted by quality of training set separation (in descending order). INPUT PARAMETERS: XY - training set, array[NPoints,NVars+1]. First NVars columns store values of independent variables, the next column stores class index (from 0 to NClasses-1) which dataset element belongs to. Fractional values are rounded to the nearest integer. The class index must be in the [0,NClasses-1] range, an exception is generated otherwise. NPoints - training set size, NPoints>=0 NVars - number of independent variables, NVars>=1 NClasses - number of classes, NClasses>=2 OUTPUT PARAMETERS: W - basis, array[NVars,NVars] columns of matrix stores basis vectors, sorted by quality of training set separation (in descending order) ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 31.05.2008 by Bochkanov Sergey *************************************************************************/void fisherldan(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, real_2d_array &w, const xparams _xparams = alglib::xdefault); void fisherldan(const real_2d_array &xy, const ae_int_t nclasses, real_2d_array &w, const xparams _xparams = alglib::xdefault);
legendre subpackagelegendrecalculate function/************************************************************************* Calculation of the value of the Legendre polynomial Pn. Parameters: n - degree, n>=0 x - argument Result: the value of the Legendre polynomial Pn at x *************************************************************************/double legendrecalculate(const ae_int_t n, const double x, const xparams _xparams = alglib::xdefault);
legendrecoefficients function/************************************************************************* Representation of Pn as C[0] + C[1]*X + ... + C[N]*X^N Input parameters: N - polynomial degree, n>=0 Output parameters: C - coefficients *************************************************************************/void legendrecoefficients(const ae_int_t n, real_1d_array &c, const xparams _xparams = alglib::xdefault);
legendresum function/************************************************************************* Summation of Legendre polynomials using Clenshaw's recurrence formula. This routine calculates c[0]*P0(x) + c[1]*P1(x) + ... + c[N]*PN(x) Parameters: n - degree, n>=0 x - argument Result: the value of the Legendre polynomial at x *************************************************************************/double legendresum(const real_1d_array &c, const ae_int_t n, const double x, const xparams _xparams = alglib::xdefault);
lincg subpackage| lincg_d_1 | Solution of sparse linear systems with CG |
lincgreport class/************************************************************************* *************************************************************************/class lincgreport { public: lincgreport(); lincgreport(const lincgreport &rhs); lincgreport& operator=(const lincgreport &rhs); virtual ~lincgreport(); ae_int_t iterationscount; ae_int_t nmv; ae_int_t terminationtype; double r2; };
lincgstate class/************************************************************************* This object stores state of the linear CG method. You should use ALGLIB functions to work with this object. Never try to access its fields directly! *************************************************************************/class lincgstate { public: lincgstate(); lincgstate(const lincgstate &rhs); lincgstate& operator=(const lincgstate &rhs); virtual ~lincgstate(); };
lincgcreate function/************************************************************************* This function initializes linear CG Solver. This solver is used to solve symmetric positive definite problems. If you want to solve nonsymmetric (or non-positive definite) problem you may use LinLSQR solver provided by ALGLIB. USAGE: 1. User initializes algorithm state with LinCGCreate() call 2. User tunes solver parameters with LinCGSetCond() and other functions 3. Optionally, user sets starting point with LinCGSetStartingPoint() 4. User calls LinCGSolveSparse() function which takes algorithm state and SparseMatrix object. 5. User calls LinCGResults() to get solution 6. Optionally, user may call LinCGSolveSparse() again to solve another problem with different matrix and/or right part without reinitializing LinCGState structure. INPUT PARAMETERS: N - problem dimension, N>0 OUTPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 14.11.2011 by Bochkanov Sergey *************************************************************************/void lincgcreate(const ae_int_t n, lincgstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
lincgresults function/************************************************************************* CG-solver: results. This function must be called after LinCGSolve INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: X - array[N], solution Rep - optimization report: * Rep.TerminationType completetion code: * -5 input matrix is either not positive definite, too large or too small * -4 overflow/underflow during solution (ill conditioned problem) * 1 ||residual||<=EpsF*||b|| * 5 MaxIts steps was taken * 7 rounding errors prevent further progress, best point found is returned * Rep.IterationsCount contains iterations count * NMV countains number of matrix-vector calculations -- ALGLIB -- Copyright 14.11.2011 by Bochkanov Sergey *************************************************************************/void lincgresults(const lincgstate &state, real_1d_array &x, lincgreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
lincgsetcond function/************************************************************************* This function sets stopping criteria. INPUT PARAMETERS: EpsF - algorithm will be stopped if norm of residual is less than EpsF*||b||. MaxIts - algorithm will be stopped if number of iterations is more than MaxIts. OUTPUT PARAMETERS: State - structure which stores algorithm state NOTES: If both EpsF and MaxIts are zero then small EpsF will be set to small value. -- ALGLIB -- Copyright 14.11.2011 by Bochkanov Sergey *************************************************************************/void lincgsetcond(lincgstate &state, const double epsf, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
lincgsetprecdiag function/************************************************************************* This function changes preconditioning settings of LinCGSolveSparse() function. LinCGSolveSparse() will use diagonal of the system matrix as preconditioner. This preconditioning mode is active by default. INPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 19.11.2012 by Bochkanov Sergey *************************************************************************/void lincgsetprecdiag(lincgstate &state, const xparams _xparams = alglib::xdefault);
lincgsetprecunit function/************************************************************************* This function changes preconditioning settings of LinCGSolveSparse() function. By default, SolveSparse() uses diagonal preconditioner, but if you want to use solver without preconditioning, you can call this function which forces solver to use unit matrix for preconditioning. INPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 19.11.2012 by Bochkanov Sergey *************************************************************************/void lincgsetprecunit(lincgstate &state, const xparams _xparams = alglib::xdefault);
lincgsetrestartfreq function/************************************************************************* This function sets restart frequency. By default, algorithm is restarted after N subsequent iterations. -- ALGLIB -- Copyright 14.11.2011 by Bochkanov Sergey *************************************************************************/void lincgsetrestartfreq(lincgstate &state, const ae_int_t srf, const xparams _xparams = alglib::xdefault);
lincgsetrupdatefreq function/************************************************************************* This function sets frequency of residual recalculations. Algorithm updates residual r_k using iterative formula, but recalculates it from scratch after each 10 iterations. It is done to avoid accumulation of numerical errors and to stop algorithm when r_k starts to grow. Such low update frequence (1/10) gives very little overhead, but makes algorithm a bit more robust against numerical errors. However, you may change it INPUT PARAMETERS: Freq - desired update frequency, Freq>=0. Zero value means that no updates will be done. -- ALGLIB -- Copyright 14.11.2011 by Bochkanov Sergey *************************************************************************/void lincgsetrupdatefreq(lincgstate &state, const ae_int_t freq, const xparams _xparams = alglib::xdefault);
lincgsetstartingpoint function/************************************************************************* This function sets starting point. By default, zero starting point is used. INPUT PARAMETERS: X - starting point, array[N] OUTPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 14.11.2011 by Bochkanov Sergey *************************************************************************/void lincgsetstartingpoint(lincgstate &state, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
lincgsetxrep function/************************************************************************* This function turns on/off reporting. INPUT PARAMETERS: State - structure which stores algorithm state NeedXRep- whether iteration reports are needed or not If NeedXRep is True, algorithm will call rep() callback function if it is provided to MinCGOptimize(). -- ALGLIB -- Copyright 14.11.2011 by Bochkanov Sergey *************************************************************************/void lincgsetxrep(lincgstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
lincgsolvesparse function/************************************************************************* Procedure for solution of A*x=b with sparse A. INPUT PARAMETERS: State - algorithm state A - sparse matrix in the CRS format (you MUST contvert it to CRS format by calling SparseConvertToCRS() function). IsUpper - whether upper or lower triangle of A is used: * IsUpper=True => only upper triangle is used and lower triangle is not referenced at all * IsUpper=False => only lower triangle is used and upper triangle is not referenced at all B - right part, array[N] RESULT: This function returns no result. You can get solution by calling LinCGResults() NOTE: this function uses lightweight preconditioning - multiplication by inverse of diag(A). If you want, you can turn preconditioning off by calling LinCGSetPrecUnit(). However, preconditioning cost is low and preconditioner is very important for solution of badly scaled problems. -- ALGLIB -- Copyright 14.11.2011 by Bochkanov Sergey *************************************************************************/void lincgsolvesparse(lincgstate &state, const sparsematrix &a, const bool isupper, const real_1d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example illustrates solution of sparse linear systems with
// conjugate gradient method.
//
// Suppose that we have linear system A*x=b with sparse symmetric
// positive definite A (represented by sparsematrix object)
// [ 5 1 ]
// [ 1 7 2 ]
// A = [ 2 8 1 ]
// [ 1 4 1 ]
// [ 1 4 ]
// and right part b
// [ 7 ]
// [ 17 ]
// b = [ 14 ]
// [ 10 ]
// [ 6 ]
// and we want to solve this system using sparse linear CG. In order
// to do so, we have to create left part (sparsematrix object) and
// right part (dense array).
//
// Initially, sparse matrix is created in the Hash-Table format,
// which allows easy initialization, but do not allow matrix to be
// used in the linear solvers. So after construction you should convert
// sparse matrix to CRS format (one suited for linear operations).
//
// It is important to note that in our example we initialize full
// matrix A, both lower and upper triangles. However, it is symmetric
// and sparse solver needs just one half of the matrix. So you may
// save about half of the space by filling only one of the triangles.
//
sparsematrix a;
sparsecreate(5, 5, a);
sparseset(a, 0, 0, 5.0);
sparseset(a, 0, 1, 1.0);
sparseset(a, 1, 0, 1.0);
sparseset(a, 1, 1, 7.0);
sparseset(a, 1, 2, 2.0);
sparseset(a, 2, 1, 2.0);
sparseset(a, 2, 2, 8.0);
sparseset(a, 2, 3, 1.0);
sparseset(a, 3, 2, 1.0);
sparseset(a, 3, 3, 4.0);
sparseset(a, 3, 4, 1.0);
sparseset(a, 4, 3, 1.0);
sparseset(a, 4, 4, 4.0);
//
// Now our matrix is fully initialized, but we have to do one more
// step - convert it from Hash-Table format to CRS format (see
// documentation on sparse matrices for more information about these
// formats).
//
// If you omit this call, ALGLIB will generate exception on the first
// attempt to use A in linear operations.
//
sparseconverttocrs(a);
//
// Initialization of the right part
//
real_1d_array b = "[7,17,14,10,6]";
//
// Now we have to create linear solver object and to use it for the
// solution of the linear system.
//
// NOTE: lincgsolvesparse() accepts additional parameter which tells
// what triangle of the symmetric matrix should be used - upper
// or lower. Because we've filled both parts of the matrix, we
// can use any part - upper or lower.
//
lincgstate s;
lincgreport rep;
real_1d_array x;
lincgcreate(5, s);
lincgsolvesparse(s, a, true, b);
lincgresults(s, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [1.000,2.000,1.000,2.000,1.000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
linlsqr subpackage| linlsqr_d_1 | Solution of sparse linear systems with CG |
linlsqrreport class/************************************************************************* *************************************************************************/class linlsqrreport { public: linlsqrreport(); linlsqrreport(const linlsqrreport &rhs); linlsqrreport& operator=(const linlsqrreport &rhs); virtual ~linlsqrreport(); ae_int_t iterationscount; ae_int_t nmv; ae_int_t terminationtype; };
linlsqrstate class/************************************************************************* This object stores state of the LinLSQR method. You should use ALGLIB functions to work with this object. *************************************************************************/class linlsqrstate { public: linlsqrstate(); linlsqrstate(const linlsqrstate &rhs); linlsqrstate& operator=(const linlsqrstate &rhs); virtual ~linlsqrstate(); };
linlsqrcreate function/************************************************************************* This function initializes linear LSQR Solver. This solver is used to solve non-symmetric (and, possibly, non-square) problems. Least squares solution is returned for non-compatible systems. USAGE: 1. User initializes algorithm state with LinLSQRCreate() call 2. User tunes solver parameters with LinLSQRSetCond() and other functions 3. User calls LinLSQRSolveSparse() function which takes algorithm state and SparseMatrix object. 4. User calls LinLSQRResults() to get solution 5. Optionally, user may call LinLSQRSolveSparse() again to solve another problem with different matrix and/or right part without reinitializing LinLSQRState structure. INPUT PARAMETERS: M - number of rows in A N - number of variables, N>0 OUTPUT PARAMETERS: State - structure which stores algorithm state NOTE: see also linlsqrcreatebuf() for version which reuses previously allocated place as much as possible. -- ALGLIB -- Copyright 30.11.2011 by Bochkanov Sergey *************************************************************************/void linlsqrcreate(const ae_int_t m, const ae_int_t n, linlsqrstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
linlsqrcreatebuf function/************************************************************************* This function initializes linear LSQR Solver. It provides exactly same functionality as linlsqrcreate(), but reuses previously allocated space as much as possible. INPUT PARAMETERS: M - number of rows in A N - number of variables, N>0 OUTPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 14.11.2018 by Bochkanov Sergey *************************************************************************/void linlsqrcreatebuf(const ae_int_t m, const ae_int_t n, linlsqrstate &state, const xparams _xparams = alglib::xdefault);
linlsqrpeekiterationscount function/************************************************************************* This function is used to peek into LSQR solver and get current iteration counter. You can safely "peek" into the solver from another thread. INPUT PARAMETERS: S - solver object RESULT: iteration counter, in [0,INF) -- ALGLIB -- Copyright 21.05.2018 by Bochkanov Sergey *************************************************************************/ae_int_t linlsqrpeekiterationscount(const linlsqrstate &s, const xparams _xparams = alglib::xdefault);
linlsqrrequesttermination function/************************************************************************* This subroutine submits request for termination of the running solver. It can be called from some other thread which wants LSQR solver to terminate (obviously, the thread running LSQR solver can not request termination because it is already busy working on LSQR). As result, solver stops at point which was "current accepted" when termination request was submitted and returns error code 8 (successful termination). Such termination is a smooth process which properly deallocates all temporaries. INPUT PARAMETERS: State - solver structure NOTE: calling this function on solver which is NOT running will have no effect. NOTE: multiple calls to this function are possible. First call is counted, subsequent calls are silently ignored. NOTE: solver clears termination flag on its start, it means that if some other thread will request termination too soon, its request will went unnoticed. -- ALGLIB -- Copyright 08.10.2014 by Bochkanov Sergey *************************************************************************/void linlsqrrequesttermination(linlsqrstate &state, const xparams _xparams = alglib::xdefault);
linlsqrresults function/************************************************************************* LSQR solver: results. This function must be called after LinLSQRSolve INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: X - array[N], solution Rep - optimization report: * Rep.TerminationType completetion code: * 1 ||Rk||<=EpsB*||B|| * 4 ||A^T*Rk||/(||A||*||Rk||)<=EpsA * 5 MaxIts steps was taken * 7 rounding errors prevent further progress, X contains best point found so far. (sometimes returned on singular systems) * 8 user requested termination via calling linlsqrrequesttermination() * Rep.IterationsCount contains iterations count * NMV countains number of matrix-vector calculations -- ALGLIB -- Copyright 30.11.2011 by Bochkanov Sergey *************************************************************************/void linlsqrresults(const linlsqrstate &state, real_1d_array &x, linlsqrreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
linlsqrsetcond function/************************************************************************* This function sets stopping criteria. INPUT PARAMETERS: EpsA - algorithm will be stopped if ||A^T*Rk||/(||A||*||Rk||)<=EpsA. EpsB - algorithm will be stopped if ||Rk||<=EpsB*||B|| MaxIts - algorithm will be stopped if number of iterations more than MaxIts. OUTPUT PARAMETERS: State - structure which stores algorithm state NOTE: if EpsA,EpsB,EpsC and MaxIts are zero then these variables will be setted as default values. -- ALGLIB -- Copyright 30.11.2011 by Bochkanov Sergey *************************************************************************/void linlsqrsetcond(linlsqrstate &state, const double epsa, const double epsb, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
linlsqrsetlambdai function/************************************************************************* This function sets optional Tikhonov regularization coefficient. It is zero by default. INPUT PARAMETERS: LambdaI - regularization factor, LambdaI>=0 OUTPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 30.11.2011 by Bochkanov Sergey *************************************************************************/void linlsqrsetlambdai(linlsqrstate &state, const double lambdai, const xparams _xparams = alglib::xdefault);
linlsqrsetprecdiag function/************************************************************************* This function changes preconditioning settings of LinCGSolveSparse() function. LinCGSolveSparse() will use diagonal of the system matrix as preconditioner. This preconditioning mode is active by default. INPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 19.11.2012 by Bochkanov Sergey *************************************************************************/void linlsqrsetprecdiag(linlsqrstate &state, const xparams _xparams = alglib::xdefault);
linlsqrsetprecunit function/************************************************************************* This function changes preconditioning settings of LinLSQQSolveSparse() function. By default, SolveSparse() uses diagonal preconditioner, but if you want to use solver without preconditioning, you can call this function which forces solver to use unit matrix for preconditioning. INPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 19.11.2012 by Bochkanov Sergey *************************************************************************/void linlsqrsetprecunit(linlsqrstate &state, const xparams _xparams = alglib::xdefault);
linlsqrsetxrep function/************************************************************************* This function turns on/off reporting. INPUT PARAMETERS: State - structure which stores algorithm state NeedXRep- whether iteration reports are needed or not If NeedXRep is True, algorithm will call rep() callback function if it is provided to MinCGOptimize(). -- ALGLIB -- Copyright 30.11.2011 by Bochkanov Sergey *************************************************************************/void linlsqrsetxrep(linlsqrstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
linlsqrsolvesparse function/************************************************************************* Procedure for solution of A*x=b with sparse A. INPUT PARAMETERS: State - algorithm state A - sparse M*N matrix in the CRS format (you MUST contvert it to CRS format by calling SparseConvertToCRS() function BEFORE you pass it to this function). B - right part, array[M] RESULT: This function returns no result. You can get solution by calling LinCGResults() NOTE: this function uses lightweight preconditioning - multiplication by inverse of diag(A). If you want, you can turn preconditioning off by calling LinLSQRSetPrecUnit(). However, preconditioning cost is low and preconditioner is very important for solution of badly scaled problems. -- ALGLIB -- Copyright 30.11.2011 by Bochkanov Sergey *************************************************************************/void linlsqrsolvesparse(linlsqrstate &state, const sparsematrix &a, const real_1d_array &b, const xparams _xparams = alglib::xdefault);
Examples: [1]
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "solvers.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example illustrates solution of sparse linear least squares problem
// with LSQR algorithm.
//
// Suppose that we have least squares problem min|A*x-b| with sparse A
// represented by sparsematrix object
// [ 1 1 ]
// [ 1 1 ]
// A = [ 2 1 ]
// [ 1 ]
// [ 1 ]
// and right part b
// [ 4 ]
// [ 2 ]
// b = [ 4 ]
// [ 1 ]
// [ 2 ]
// and we want to solve this system in the least squares sense using
// LSQR algorithm. In order to do so, we have to create left part
// (sparsematrix object) and right part (dense array).
//
// Initially, sparse matrix is created in the Hash-Table format,
// which allows easy initialization, but do not allow matrix to be
// used in the linear solvers. So after construction you should convert
// sparse matrix to CRS format (one suited for linear operations).
//
sparsematrix a;
sparsecreate(5, 2, a);
sparseset(a, 0, 0, 1.0);
sparseset(a, 0, 1, 1.0);
sparseset(a, 1, 0, 1.0);
sparseset(a, 1, 1, 1.0);
sparseset(a, 2, 0, 2.0);
sparseset(a, 2, 1, 1.0);
sparseset(a, 3, 0, 1.0);
sparseset(a, 4, 1, 1.0);
//
// Now our matrix is fully initialized, but we have to do one more
// step - convert it from Hash-Table format to CRS format (see
// documentation on sparse matrices for more information about these
// formats).
//
// If you omit this call, ALGLIB will generate exception on the first
// attempt to use A in linear operations.
//
sparseconverttocrs(a);
//
// Initialization of the right part
//
real_1d_array b = "[4,2,4,1,2]";
//
// Now we have to create linear solver object and to use it for the
// solution of the linear system.
//
linlsqrstate s;
linlsqrreport rep;
real_1d_array x;
linlsqrcreate(5, 2, s);
linlsqrsolvesparse(s, a, b);
linlsqrresults(s, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 4
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [1.000,2.000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
linreg subpackage| linreg_d_basic | Linear regression used to build the very basic model and unpack coefficients |
linearmodel class/************************************************************************* *************************************************************************/class linearmodel { public: linearmodel(); linearmodel(const linearmodel &rhs); linearmodel& operator=(const linearmodel &rhs); virtual ~linearmodel(); };
lrreport class/************************************************************************* LRReport structure contains additional information about linear model: * C - covariation matrix, array[0..NVars,0..NVars]. C[i,j] = Cov(A[i],A[j]) * RMSError - root mean square error on a training set * AvgError - average error on a training set * AvgRelError - average relative error on a training set (excluding observations with zero function value). * CVRMSError - leave-one-out cross-validation estimate of generalization error. Calculated using fast algorithm with O(NVars*NPoints) complexity. * CVAvgError - cross-validation estimate of average error * CVAvgRelError - cross-validation estimate of average relative error All other fields of the structure are intended for internal use and should not be used outside ALGLIB. *************************************************************************/class lrreport { public: lrreport(); lrreport(const lrreport &rhs); lrreport& operator=(const lrreport &rhs); virtual ~lrreport(); real_2d_array c; double rmserror; double avgerror; double avgrelerror; double cvrmserror; double cvavgerror; double cvavgrelerror; ae_int_t ncvdefects; integer_1d_array cvdefects; };
lravgerror function/************************************************************************* Average error on the test set INPUT PARAMETERS: LM - linear model XY - test set NPoints - test set size RESULT: average error. -- ALGLIB -- Copyright 30.08.2008 by Bochkanov Sergey *************************************************************************/double lravgerror(const linearmodel &lm, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
lravgrelerror function/************************************************************************* RMS error on the test set INPUT PARAMETERS: LM - linear model XY - test set NPoints - test set size RESULT: average relative error. -- ALGLIB -- Copyright 30.08.2008 by Bochkanov Sergey *************************************************************************/double lravgrelerror(const linearmodel &lm, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
lrbuild function/************************************************************************* Linear regression Subroutine builds model: Y = A(0)*X[0] + ... + A(N-1)*X[N-1] + A(N) and model found in ALGLIB format, covariation matrix, training set errors (rms, average, average relative) and leave-one-out cross-validation estimate of the generalization error. CV estimate calculated using fast algorithm with O(NPoints*NVars) complexity. When covariation matrix is calculated standard deviations of function values are assumed to be equal to RMS error on the training set. INPUT PARAMETERS: XY - training set, array [0..NPoints-1,0..NVars]: * NVars columns - independent variables * last column - dependent variable NPoints - training set size, NPoints>NVars+1. An exception is generated otherwise. NVars - number of independent variables OUTPUT PARAMETERS: LM - linear model in the ALGLIB format. Use subroutines of this unit to work with the model. Rep - additional results, see comments on LRReport structure. -- ALGLIB -- Copyright 02.08.2008 by Bochkanov Sergey *************************************************************************/void lrbuild(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, linearmodel &lm, lrreport &rep, const xparams _xparams = alglib::xdefault); void lrbuild(const real_2d_array &xy, linearmodel &lm, lrreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
lrbuilds function/************************************************************************* Linear regression Variant of LRBuild which uses vector of standatd deviations (errors in function values). INPUT PARAMETERS: XY - training set, array [0..NPoints-1,0..NVars]: * NVars columns - independent variables * last column - dependent variable S - standard deviations (errors in function values) array[NPoints], S[i]>0. NPoints - training set size, NPoints>NVars+1 NVars - number of independent variables OUTPUT PARAMETERS: LM - linear model in the ALGLIB format. Use subroutines of this unit to work with the model. Rep - additional results, see comments on LRReport structure. -- ALGLIB -- Copyright 02.08.2008 by Bochkanov Sergey *************************************************************************/void lrbuilds(const real_2d_array &xy, const real_1d_array &s, const ae_int_t npoints, const ae_int_t nvars, linearmodel &lm, lrreport &rep, const xparams _xparams = alglib::xdefault); void lrbuilds(const real_2d_array &xy, const real_1d_array &s, linearmodel &lm, lrreport &rep, const xparams _xparams = alglib::xdefault);
lrbuildz function/************************************************************************* Like LRBuild but builds model Y = A(0)*X[0] + ... + A(N-1)*X[N-1] i.e. with zero constant term. -- ALGLIB -- Copyright 30.10.2008 by Bochkanov Sergey *************************************************************************/void lrbuildz(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, linearmodel &lm, lrreport &rep, const xparams _xparams = alglib::xdefault); void lrbuildz(const real_2d_array &xy, linearmodel &lm, lrreport &rep, const xparams _xparams = alglib::xdefault);
lrbuildzs function/************************************************************************* Like LRBuildS, but builds model Y = A(0)*X[0] + ... + A(N-1)*X[N-1] i.e. with zero constant term. -- ALGLIB -- Copyright 30.10.2008 by Bochkanov Sergey *************************************************************************/void lrbuildzs(const real_2d_array &xy, const real_1d_array &s, const ae_int_t npoints, const ae_int_t nvars, linearmodel &lm, lrreport &rep, const xparams _xparams = alglib::xdefault); void lrbuildzs(const real_2d_array &xy, const real_1d_array &s, linearmodel &lm, lrreport &rep, const xparams _xparams = alglib::xdefault);
lrpack function/************************************************************************* "Packs" coefficients and creates linear model in ALGLIB format (LRUnpack reversed). INPUT PARAMETERS: V - coefficients, array[0..NVars] NVars - number of independent variables OUTPUT PAREMETERS: LM - linear model. -- ALGLIB -- Copyright 30.08.2008 by Bochkanov Sergey *************************************************************************/void lrpack(const real_1d_array &v, const ae_int_t nvars, linearmodel &lm, const xparams _xparams = alglib::xdefault); void lrpack(const real_1d_array &v, linearmodel &lm, const xparams _xparams = alglib::xdefault);
lrprocess function/************************************************************************* Procesing INPUT PARAMETERS: LM - linear model X - input vector, array[0..NVars-1]. Result: value of linear model regression estimate -- ALGLIB -- Copyright 03.09.2008 by Bochkanov Sergey *************************************************************************/double lrprocess(const linearmodel &lm, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
lrrmserror function/************************************************************************* RMS error on the test set INPUT PARAMETERS: LM - linear model XY - test set NPoints - test set size RESULT: root mean square error. -- ALGLIB -- Copyright 30.08.2008 by Bochkanov Sergey *************************************************************************/double lrrmserror(const linearmodel &lm, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
lrunpack function/************************************************************************* Unpacks coefficients of linear model. INPUT PARAMETERS: LM - linear model in ALGLIB format OUTPUT PARAMETERS: V - coefficients, array[0..NVars] constant term (intercept) is stored in the V[NVars]. NVars - number of independent variables (one less than number of coefficients) -- ALGLIB -- Copyright 30.08.2008 by Bochkanov Sergey *************************************************************************/void lrunpack(const linearmodel &lm, real_1d_array &v, ae_int_t &nvars, const xparams _xparams = alglib::xdefault);
Examples: [1]
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// In this example we demonstrate linear fitting by f(x|a) = a*exp(0.5*x).
//
// We have:
// * xy - matrix of basic function values (exp(0.5*x)) and expected values
//
real_2d_array xy = "[[0.606531,1.133719],[0.670320,1.306522],[0.740818,1.504604],[0.818731,1.554663],[0.904837,1.884638],[1.000000,2.072436],[1.105171,2.257285],[1.221403,2.534068],[1.349859,2.622017],[1.491825,2.897713],[1.648721,3.219371]]";
ae_int_t nvars;
linearmodel model;
lrreport rep;
real_1d_array c;
lrbuildz(xy, 11, 1, model, rep);
lrunpack(model, c, nvars);
printf("%s\n", c.tostring(4).c_str()); // EXPECTED: [1.98650,0.00000]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
logit subpackagelogitmodel class/************************************************************************* *************************************************************************/class logitmodel { public: logitmodel(); logitmodel(const logitmodel &rhs); logitmodel& operator=(const logitmodel &rhs); virtual ~logitmodel(); };
mnlreport class/************************************************************************* MNLReport structure contains information about training process: * NGrad - number of gradient calculations * NHess - number of Hessian calculations *************************************************************************/class mnlreport { public: mnlreport(); mnlreport(const mnlreport &rhs); mnlreport& operator=(const mnlreport &rhs); virtual ~mnlreport(); ae_int_t ngrad; ae_int_t nhess; };
mnlavgce function/************************************************************************* Average cross-entropy (in bits per element) on the test set INPUT PARAMETERS: LM - logit model XY - test set NPoints - test set size RESULT: CrossEntropy/(NPoints*ln(2)). -- ALGLIB -- Copyright 10.09.2008 by Bochkanov Sergey *************************************************************************/double mnlavgce(logitmodel &lm, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
mnlavgerror function/************************************************************************* Average error on the test set INPUT PARAMETERS: LM - logit model XY - test set NPoints - test set size RESULT: average error (error when estimating posterior probabilities). -- ALGLIB -- Copyright 30.08.2008 by Bochkanov Sergey *************************************************************************/double mnlavgerror(logitmodel &lm, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
mnlavgrelerror function/************************************************************************* Average relative error on the test set INPUT PARAMETERS: LM - logit model XY - test set NPoints - test set size RESULT: average relative error (error when estimating posterior probabilities). -- ALGLIB -- Copyright 30.08.2008 by Bochkanov Sergey *************************************************************************/double mnlavgrelerror(logitmodel &lm, const real_2d_array &xy, const ae_int_t ssize, const xparams _xparams = alglib::xdefault);
mnlclserror function/************************************************************************* Classification error on test set = MNLRelClsError*NPoints -- ALGLIB -- Copyright 10.09.2008 by Bochkanov Sergey *************************************************************************/ae_int_t mnlclserror(logitmodel &lm, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
mnlpack function/************************************************************************* "Packs" coefficients and creates logit model in ALGLIB format (MNLUnpack reversed). INPUT PARAMETERS: A - model (see MNLUnpack) NVars - number of independent variables NClasses - number of classes OUTPUT PARAMETERS: LM - logit model. -- ALGLIB -- Copyright 10.09.2008 by Bochkanov Sergey *************************************************************************/void mnlpack(const real_2d_array &a, const ae_int_t nvars, const ae_int_t nclasses, logitmodel &lm, const xparams _xparams = alglib::xdefault);
mnlprocess function/************************************************************************* Procesing INPUT PARAMETERS: LM - logit model, passed by non-constant reference (some fields of structure are used as temporaries when calculating model output). X - input vector, array[0..NVars-1]. Y - (possibly) preallocated buffer; if size of Y is less than NClasses, it will be reallocated.If it is large enough, it is NOT reallocated, so we can save some time on reallocation. OUTPUT PARAMETERS: Y - result, array[0..NClasses-1] Vector of posterior probabilities for classification task. -- ALGLIB -- Copyright 10.09.2008 by Bochkanov Sergey *************************************************************************/void mnlprocess(logitmodel &lm, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
mnlprocessi function/************************************************************************* 'interactive' variant of MNLProcess for languages like Python which support constructs like "Y = MNLProcess(LM,X)" and interactive mode of the 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 10.09.2008 by Bochkanov Sergey *************************************************************************/void mnlprocessi(logitmodel &lm, const real_1d_array &x, real_1d_array &y, const xparams _xparams = alglib::xdefault);
mnlrelclserror function/************************************************************************* Relative classification error on the test set INPUT PARAMETERS: LM - logit model XY - test set NPoints - test set size RESULT: percent of incorrectly classified cases. -- ALGLIB -- Copyright 10.09.2008 by Bochkanov Sergey *************************************************************************/double mnlrelclserror(logitmodel &lm, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
mnlrmserror function/************************************************************************* RMS error on the test set INPUT PARAMETERS: LM - logit model XY - test set NPoints - test set size RESULT: root mean square error (error when estimating posterior probabilities). -- ALGLIB -- Copyright 30.08.2008 by Bochkanov Sergey *************************************************************************/double mnlrmserror(logitmodel &lm, const real_2d_array &xy, const ae_int_t npoints, const xparams _xparams = alglib::xdefault);
mnltrainh function/************************************************************************* This subroutine trains logit model. INPUT PARAMETERS: XY - training set, array[0..NPoints-1,0..NVars] First NVars columns store values of independent variables, next column stores number of class (from 0 to NClasses-1) which dataset element belongs to. Fractional values are rounded to nearest integer. NPoints - training set size, NPoints>=1 NVars - number of independent variables, NVars>=1 NClasses - number of classes, NClasses>=2 OUTPUT PARAMETERS: Info - return code: * -2, if there is a point with class number outside of [0..NClasses-1]. * -1, if incorrect parameters was passed (NPoints<NVars+2, NVars<1, NClasses<2). * 1, if task has been solved LM - model built Rep - training report -- ALGLIB -- Copyright 10.09.2008 by Bochkanov Sergey *************************************************************************/void mnltrainh(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, ae_int_t &info, logitmodel &lm, mnlreport &rep, const xparams _xparams = alglib::xdefault);
mnlunpack function/************************************************************************* Unpacks coefficients of logit model. Logit model have form: P(class=i) = S(i) / (S(0) + S(1) + ... +S(M-1)) S(i) = Exp(A[i,0]*X[0] + ... + A[i,N-1]*X[N-1] + A[i,N]), when i<M-1 S(M-1) = 1 INPUT PARAMETERS: LM - logit model in ALGLIB format OUTPUT PARAMETERS: V - coefficients, array[0..NClasses-2,0..NVars] NVars - number of independent variables NClasses - number of classes -- ALGLIB -- Copyright 10.09.2008 by Bochkanov Sergey *************************************************************************/void mnlunpack(const logitmodel &lm, real_2d_array &a, ae_int_t &nvars, ae_int_t &nclasses, const xparams _xparams = alglib::xdefault);
lpsolvers subpackage| lpsolvers_basic | Basic linear programming example |
minlpreport class/************************************************************************* This structure stores optimization report: * f target function value * lagbc Lagrange coefficients for box constraints * laglc Lagrange coefficients for linear constraints * y dual variables * stats array[N+M], statuses of box (N) and linear (M) constraints. This array is filled only by DSS algorithm because IPM always stops at INTERIOR point: * stats[i]>0 => constraint at upper bound (also used for free non-basic variables set to zero) * stats[i]<0 => constraint at lower bound * stats[i]=0 => constraint is inactive, basic variable * primalerror primal feasibility error * dualerror dual feasibility error * slackerror complementary slackness error * iterationscount iteration count * terminationtype completion code (see below) COMPLETION CODES Completion codes: * -4 LP problem is primal unbounded (dual infeasible) * -3 LP problem is primal infeasible (dual unbounded) * 1..4 successful completion * 5 MaxIts steps was taken * 7 stopping conditions are too stringent, further improvement is impossible, X contains best point found so far. LAGRANGE COEFFICIENTS Positive Lagrange coefficient means that constraint is at its upper bound. Negative coefficient means that constraint is at its lower bound. It is expected that at the solution the dual feasibility condition holds: C + SUM(Ei*LagBC[i],i=0..n-1) + SUM(Ai*LagLC[i],i=0..m-1) ~ 0 where * C is a cost vector (linear term) * Ei is a vector with 1.0 at position I and 0 in other positions * Ai is an I-th row of linear constraint matrix *************************************************************************/class minlpreport { public: minlpreport(); minlpreport(const minlpreport &rhs); minlpreport& operator=(const minlpreport &rhs); virtual ~minlpreport(); double f; real_1d_array lagbc; real_1d_array laglc; real_1d_array y; integer_1d_array stats; double primalerror; double dualerror; double slackerror; ae_int_t iterationscount; ae_int_t terminationtype; };
minlpstate class/************************************************************************* This object stores linear solver state. You should use functions provided by MinLP subpackage to work with this object *************************************************************************/class minlpstate { public: minlpstate(); minlpstate(const minlpstate &rhs); minlpstate& operator=(const minlpstate &rhs); virtual ~minlpstate(); };
minlpaddlc2 function/************************************************************************* This function appends two-sided linear constraint AL <= A*x <= AU to the list of currently present constraints. Constraint is passed in compressed format: as list of non-zero entries of coefficient vector A. Such approach is more efficient than dense storage for highly sparse constraint vectors. INPUT PARAMETERS: State - structure previously allocated with minlpcreate() call. IdxA - array[NNZ], indexes of non-zero elements of A: * can be unsorted * can include duplicate indexes (corresponding entries of ValA[] will be summed) ValA - array[NNZ], values of non-zero elements of A NNZ - number of non-zero coefficients in A AL, AU - lower and upper bounds; * AL=AU => equality constraint A*x * AL<AU => two-sided constraint AL<=A*x<=AU * AL=-INF => one-sided constraint A*x<=AU * AU=+INF => one-sided constraint AL<=A*x * AL=-INF, AU=+INF => constraint is ignored -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpaddlc2(minlpstate &state, const integer_1d_array &idxa, const real_1d_array &vala, const ae_int_t nnz, const double al, const double au, const xparams _xparams = alglib::xdefault);
minlpaddlc2dense function/************************************************************************* This function appends two-sided linear constraint AL <= A*x <= AU to the list of currently present constraints. This version accepts dense constraint vector as input, but sparsifies it for internal storage and processing. Thus, time to add one constraint in is O(N) - we have to scan entire array of length N. Sparse version of this function is order of magnitude faster for constraints with just a few nonzeros per row. INPUT PARAMETERS: State - structure previously allocated with minlpcreate() call. A - linear constraint coefficient, array[N], right side is NOT included. AL, AU - lower and upper bounds; * AL=AU => equality constraint Ai*x * AL<AU => two-sided constraint AL<=A*x<=AU * AL=-INF => one-sided constraint Ai*x<=AU * AU=+INF => one-sided constraint AL<=Ai*x * AL=-INF, AU=+INF => constraint is ignored -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpaddlc2dense(minlpstate &state, const real_1d_array &a, const double al, const double au, const xparams _xparams = alglib::xdefault);
minlpcreate function/************************************************************************* LINEAR PROGRAMMING The subroutine creates LP solver. After initial creation it contains default optimization problem with zero cost vector and all variables being fixed to zero values and no constraints. In order to actually solve something you should: * set cost vector with minlpsetcost() * set variable bounds with minlpsetbc() or minlpsetbcall() * specify constraint matrix with one of the following functions: [*] minlpsetlc() for dense one-sided constraints [*] minlpsetlc2dense() for dense two-sided constraints [*] minlpsetlc2() for sparse two-sided constraints [*] minlpaddlc2dense() to add one dense row to constraint matrix [*] minlpaddlc2() to add one row to constraint matrix (compressed format) * call minlpoptimize() to run the solver and minlpresults() to get the solution vector and additional information. By default, LP solver uses best algorithm available. As of ALGLIB 3.17, sparse interior point (barrier) solver is used. Future releases of ALGLIB may introduce other solvers. User may choose specific LP algorithm by calling: * minlpsetalgodss() for revised dual simplex method with DSE pricing and bounds flipping ratio test (aka long dual step). Large-scale sparse LU solverwith Forest-Tomlin update is used internally as linear algebra driver. * minlpsetalgoipm() for sparse interior point method INPUT PARAMETERS: N - problem size OUTPUT PARAMETERS: State - optimizer in the default state -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpcreate(const ae_int_t n, minlpstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlpoptimize function/************************************************************************* This function solves LP problem. INPUT PARAMETERS: State - algorithm state You should use minlpresults() function to access results after calls to this function. -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey. *************************************************************************/void minlpoptimize(minlpstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlpresults function/************************************************************************* LP solver results INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: X - array[N], solution (on failure: last trial point) Rep - optimization report. You should check Rep.TerminationType, which contains completion code, and you may check another fields which contain another information about algorithm functioning. Failure codes returned by algorithm are: * -4 LP problem is primal unbounded (dual infeasible) * -3 LP problem is primal infeasible (dual unbounded) * -2 IPM solver detected that problem is either infeasible or unbounded Success codes: * 1..4 successful completion * 5 MaxIts steps was taken -- ALGLIB -- Copyright 11.01.2011 by Bochkanov Sergey *************************************************************************/void minlpresults(const minlpstate &state, real_1d_array &x, minlpreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlpresultsbuf function/************************************************************************* LP results Buffered implementation of MinLPResults() which uses pre-allocated buffer to store X[]. If buffer size is too small, it resizes buffer. It is intended to be used in the inner cycles of performance critical algorithms where array reallocation penalty is too large to be ignored. -- ALGLIB -- Copyright 11.01.2011 by Bochkanov Sergey *************************************************************************/void minlpresultsbuf(const minlpstate &state, real_1d_array &x, minlpreport &rep, const xparams _xparams = alglib::xdefault);
minlpsetalgodss function/************************************************************************* This function sets LP algorithm to revised dual simplex method. ALGLIB implementation of dual simplex method supports advanced performance and stability improvements like DSE pricing , bounds flipping ratio test (aka long dual step), Forest-Tomlin update, shifting. INPUT PARAMETERS: State - optimizer Eps - stopping condition, Eps>=0: * should be small number about 1E-6 or 1E-7. * zero value means that solver automatically selects good value (can be different in different ALGLIB versions) * default value is zero Algorithm stops when relative error is less than Eps. ===== TRACING DSS SOLVER ================================================= DSS solver supports advanced tracing capabilities. You can trace algorithm output by specifying following trace symbols (case-insensitive) by means of trace_file() call: * 'DSS' - for basic trace of algorithm steps and decisions. Only short scalars (function values and deltas) are printed. N-dimensional quantities like search directions are NOT printed. * 'DSS.DETAILED'- for output of points being visited and search directions This symbol also implicitly defines 'DSS'. You can control output format by additionally specifying: * nothing to output in 6-digit exponential format * 'PREC.E15' to output in 15-digit exponential format * 'PREC.F6' to output in 6-digit fixed-point format By default trace is disabled and adds no overhead to the optimization process. However, specifying any of the symbols adds some formatting and output-related overhead. You may specify multiple symbols by separating them with commas: > > alglib::trace_file("DSS,PREC.F6", "path/to/trace.log") > -- ALGLIB -- Copyright 08.11.2020 by Bochkanov Sergey *************************************************************************/void minlpsetalgodss(minlpstate &state, const double eps, const xparams _xparams = alglib::xdefault);
minlpsetalgoipm function/************************************************************************* This function sets LP algorithm to sparse interior point method. ALGORITHM INFORMATION: * this algorithm is our implementation of interior point method as formulated by R.J.Vanderbei, with minor modifications to the algorithm (damped Newton directions are extensively used) * like all interior point methods, this algorithm tends to converge in roughly same number of iterations (between 15 and 50) independently from the problem dimensionality INPUT PARAMETERS: State - optimizer Eps - stopping condition, Eps>=0: * should be small number about 1E-6 or 1E-8. * zero value means that solver automatically selects good value (can be different in different ALGLIB versions) * default value is zero Algorithm stops when primal error AND dual error AND duality gap are less than Eps. ===== TRACING IPM SOLVER ================================================= IPM solver supports advanced tracing capabilities. You can trace algorithm output by specifying following trace symbols (case-insensitive) by means of trace_file() call: * 'IPM' - for basic trace of algorithm steps and decisions. Only short scalars (function values and deltas) are printed. N-dimensional quantities like search directions are NOT printed. * 'IPM.DETAILED'- for output of points being visited and search directions This symbol also implicitly defines 'IPM'. You can control output format by additionally specifying: * nothing to output in 6-digit exponential format * 'PREC.E15' to output in 15-digit exponential format * 'PREC.F6' to output in 6-digit fixed-point format By default trace is disabled and adds no overhead to the optimization process. However, specifying any of the symbols adds some formatting and output-related overhead. You may specify multiple symbols by separating them with commas: > > alglib::trace_file("IPM,PREC.F6", "path/to/trace.log") > -- ALGLIB -- Copyright 08.11.2020 by Bochkanov Sergey *************************************************************************/void minlpsetalgoipm(minlpstate &state, const double eps, const xparams _xparams = alglib::xdefault); void minlpsetalgoipm(minlpstate &state, const xparams _xparams = alglib::xdefault);
minlpsetbc function/************************************************************************* This function sets box constraints for LP solver (all variables at once, different constraints for different variables). The default state of constraints is to have all variables fixed at zero. You have to overwrite it by your own constraint vector. Constraint status is preserved until constraints are explicitly overwritten with another minlpsetbc() call, overwritten with minlpsetbcall(), or partially overwritten with minlmsetbci() call. Following types of constraints are supported: DESCRIPTION CONSTRAINT HOW TO SPECIFY fixed variable x[i]=Bnd[i] BndL[i]=BndU[i] lower bound BndL[i]<=x[i] BndU[i]=+INF upper bound x[i]<=BndU[i] BndL[i]=-INF range BndL[i]<=x[i]<=BndU[i] ... free variable - BndL[I]=-INF, BndU[I]+INF INPUT PARAMETERS: State - structure stores algorithm state BndL - lower bounds, array[N]. BndU - upper bounds, array[N]. NOTE: infinite values can be specified by means of Double.PositiveInfinity and Double.NegativeInfinity (in C#) and alglib::fp_posinf and alglib::fp_neginf (in C++). NOTE: you may replace infinities by very small/very large values, but it is not recommended because large numbers may introduce large numerical errors in the algorithm. NOTE: if constraints for all variables are same you may use minlpsetbcall() which allows to specify constraints without using arrays. NOTE: BndL>BndU will result in LP problem being recognized as infeasible. -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpsetbc(minlpstate &state, const real_1d_array &bndl, const real_1d_array &bndu, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlpsetbcall function/************************************************************************* This function sets box constraints for LP solver (all variables at once, same constraints for all variables) The default state of constraints is to have all variables fixed at zero. You have to overwrite it by your own constraint vector. Constraint status is preserved until constraints are explicitly overwritten with another minlpsetbc() call or partially overwritten with minlpsetbcall(). Following types of constraints are supported: DESCRIPTION CONSTRAINT HOW TO SPECIFY fixed variable x[i]=Bnd[i] BndL[i]=BndU[i] lower bound BndL[i]<=x[i] BndU[i]=+INF upper bound x[i]<=BndU[i] BndL[i]=-INF range BndL[i]<=x[i]<=BndU[i] ... free variable - BndL[I]=-INF, BndU[I]+INF INPUT PARAMETERS: State - structure stores algorithm state BndL - lower bound, same for all variables BndU - upper bound, same for all variables NOTE: infinite values can be specified by means of Double.PositiveInfinity and Double.NegativeInfinity (in C#) and alglib::fp_posinf and alglib::fp_neginf (in C++). NOTE: you may replace infinities by very small/very large values, but it is not recommended because large numbers may introduce large numerical errors in the algorithm. NOTE: minlpsetbc() can be used to specify different constraints for different variables. NOTE: BndL>BndU will result in LP problem being recognized as infeasible. -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpsetbcall(minlpstate &state, const double bndl, const double bndu, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlpsetbci function/************************************************************************* This function sets box constraints for I-th variable (other variables are not modified). The default state of constraints is to have all variables fixed at zero. You have to overwrite it by your own constraint vector. Following types of constraints are supported: DESCRIPTION CONSTRAINT HOW TO SPECIFY fixed variable x[i]=Bnd[i] BndL[i]=BndU[i] lower bound BndL[i]<=x[i] BndU[i]=+INF upper bound x[i]<=BndU[i] BndL[i]=-INF range BndL[i]<=x[i]<=BndU[i] ... free variable - BndL[I]=-INF, BndU[I]+INF INPUT PARAMETERS: State - structure stores algorithm state I - variable index, in [0,N) BndL - lower bound for I-th variable BndU - upper bound for I-th variable NOTE: infinite values can be specified by means of Double.PositiveInfinity and Double.NegativeInfinity (in C#) and alglib::fp_posinf and alglib::fp_neginf (in C++). NOTE: you may replace infinities by very small/very large values, but it is not recommended because large numbers may introduce large numerical errors in the algorithm. NOTE: minlpsetbc() can be used to specify different constraints for different variables. NOTE: BndL>BndU will result in LP problem being recognized as infeasible. -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpsetbci(minlpstate &state, const ae_int_t i, const double bndl, const double bndu, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlpsetcost function/************************************************************************* This function sets cost term for LP solver. By default, cost term is zero. INPUT PARAMETERS: State - structure which stores algorithm state C - cost term, array[N]. -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpsetcost(minlpstate &state, const real_1d_array &c, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlpsetlc function/************************************************************************* This function sets one-sided linear constraints A*x ~ AU, where "~" can be a mix of "<=", "=" and ">=". IMPORTANT: this function is provided here for compatibility with the rest of ALGLIB optimizers which accept constraints in format like this one. Many real-life problems feature two-sided constraints like a0 <= a*x <= a1. It is really inefficient to add them as a pair of one-sided constraints. Use minlpsetlc2dense(), minlpsetlc2(), minlpaddlc2() (or its sparse version) wherever possible. INPUT PARAMETERS: State - structure previously allocated with minlpcreate() call. A - linear constraints, array[K,N+1]. Each row of A represents one constraint, with first N elements being linear coefficients, and last element being right side. CT - constraint types, array[K]: * if CT[i]>0, then I-th constraint is A[i,*]*x >= A[i,n] * if CT[i]=0, then I-th constraint is A[i,*]*x = A[i,n] * if CT[i]<0, then I-th constraint is A[i,*]*x <= A[i,n] K - number of equality/inequality constraints, K>=0; if not given, inferred from sizes of A and CT. -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpsetlc(minlpstate &state, const real_2d_array &a, const integer_1d_array &ct, const ae_int_t k, const xparams _xparams = alglib::xdefault); void minlpsetlc(minlpstate &state, const real_2d_array &a, const integer_1d_array &ct, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlpsetlc2 function/************************************************************************* This function sets two-sided linear constraints AL <= A*x <= AU with sparse constraining matrix A. Recommended for large-scale problems. This function overwrites linear (non-box) constraints set by previous calls (if such calls were made). INPUT PARAMETERS: State - structure previously allocated with minlpcreate() call. A - sparse matrix with size [K,N] (exactly!). Each row of A represents one general linear constraint. A can be stored in any sparse storage format. AL, AU - lower and upper bounds, array[K]; * AL[i]=AU[i] => equality constraint Ai*x * AL[i]<AU[i] => two-sided constraint AL[i]<=Ai*x<=AU[i] * AL[i]=-INF => one-sided constraint Ai*x<=AU[i] * AU[i]=+INF => one-sided constraint AL[i]<=Ai*x * AL[i]=-INF, AU[i]=+INF => constraint is ignored K - number of equality/inequality constraints, K>=0. If K=0 is specified, A, AL, AU are ignored. -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpsetlc2(minlpstate &state, const sparsematrix &a, const real_1d_array &al, const real_1d_array &au, const ae_int_t k, const xparams _xparams = alglib::xdefault);
minlpsetlc2dense function/************************************************************************* This function sets two-sided linear constraints AL <= A*x <= AU. This version accepts dense matrix as input; internally LP solver uses sparse storage anyway (most LP problems are sparse), but for your convenience it may accept dense inputs. This function overwrites linear constraints set by previous calls (if such calls were made). We recommend you to use sparse version of this function unless you solve small-scale LP problem (less than few hundreds of variables). NOTE: there also exist several versions of this function: * one-sided dense version which accepts constraints in the same format as one used by QP and NLP solvers * two-sided sparse version which accepts sparse matrix * two-sided dense version which allows you to add constraints row by row * two-sided sparse version which allows you to add constraints row by row INPUT PARAMETERS: State - structure previously allocated with minlpcreate() call. A - linear constraints, array[K,N]. Each row of A represents one constraint. One-sided inequality constraints, two- sided inequality constraints, equality constraints are supported (see below) AL, AU - lower and upper bounds, array[K]; * AL[i]=AU[i] => equality constraint Ai*x * AL[i]<AU[i] => two-sided constraint AL[i]<=Ai*x<=AU[i] * AL[i]=-INF => one-sided constraint Ai*x<=AU[i] * AU[i]=+INF => one-sided constraint AL[i]<=Ai*x * AL[i]=-INF, AU[i]=+INF => constraint is ignored K - number of equality/inequality constraints, K>=0; if not given, inferred from sizes of A, AL, AU. -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpsetlc2dense(minlpstate &state, const real_2d_array &a, const real_1d_array &al, const real_1d_array &au, const ae_int_t k, const xparams _xparams = alglib::xdefault); void minlpsetlc2dense(minlpstate &state, const real_2d_array &a, const real_1d_array &al, const real_1d_array &au, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlpsetscale function/************************************************************************* This function sets scaling coefficients. ALGLIB optimizers use scaling matrices to test stopping conditions and as preconditioner. Scale of the I-th variable is a translation invariant measure of: a) "how large" the variable is b) how large the step should be to make significant changes in the function INPUT PARAMETERS: State - structure stores algorithm state S - array[N], non-zero scaling coefficients S[i] may be negative, sign doesn't matter. -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpsetscale(minlpstate &state, const real_1d_array &s, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates how to minimize
//
// F(x0,x1) = -0.1*x0 - x1
//
// subject to box constraints
//
// -1 <= x0,x1 <= +1
//
// and general linear constraints
//
// x0 - x1 >= -1
// x0 + x1 <= 1
//
// We use dual simplex solver provided by ALGLIB for this task. Box
// constraints are specified by means of constraint vectors bndl and
// bndu (we have bndl<=x<=bndu). General linear constraints are
// specified as AL<=A*x<=AU, with AL/AU being 2x1 vectors and A being
// 2x2 matrix.
//
// NOTE: some/all components of AL/AU can be +-INF, same applies to
// bndl/bndu. You can also have AL[I]=AU[i] (as well as
// BndL[i]=BndU[i]).
//
real_2d_array a = "[[1,-1],[1,+1]]";
real_1d_array al = "[-1,-inf]";
real_1d_array au = "[+inf,+1]";
real_1d_array c = "[-0.1,-1]";
real_1d_array s = "[1,1]";
real_1d_array bndl = "[-1,-1]";
real_1d_array bndu = "[+1,+1]";
real_1d_array x;
minlpstate state;
minlpreport rep;
minlpcreate(2, state);
//
// Set cost vector, box constraints, general linear constraints.
//
// Box constraints can be set in one call to minlpsetbc() or minlpsetbcall()
// (latter sets same constraints for all variables and accepts two scalars
// instead of two vectors).
//
// General linear constraints can be specified in several ways:
// * minlpsetlc2dense() - accepts dense 2D array as input; sometimes this
// approach is more convenient, although less memory-efficient.
// * minlpsetlc2() - accepts sparse matrix as input
// * minlpaddlc2dense() - appends one row to the current set of constraints;
// row being appended is specified as dense vector
// * minlpaddlc2() - appends one row to the current set of constraints;
// row being appended is specified as sparse set of elements
// Independently from specific function being used, LP solver uses sparse
// storage format for internal representation of constraints.
//
minlpsetcost(state, c);
minlpsetbc(state, bndl, bndu);
minlpsetlc2dense(state, a, al, au, 2);
//
// Set scale of the parameters.
//
// It is strongly recommended that you set scale of your variables.
// Knowing their scales is essential for evaluation of stopping criteria
// and for preconditioning of the algorithm steps.
// You can find more information on scaling at http://www.alglib.net/optimization/scaling.php
//
minlpsetscale(state, s);
//
// Solve with the sparse IPM.
//
// Commercial ALGLIB can parallelize sparse Cholesky factorization which is the
// most time-consuming part of the algorithm. See the ALGLIB Reference Manual for
// more information on how to activate parallelism support.
//
minlpsetalgoipm(state);
minlpoptimize(state);
minlpresults(state, x, rep);
printf("%s\n", x.tostring(3).c_str()); // EXPECTED: [0,1]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
lsfit subpackage| lsfit_d_lin | Unconstrained (general) linear least squares fitting with and without weights | |
| lsfit_d_linc | Constrained (general) linear least squares fitting with and without weights | |
| lsfit_d_nlf | Nonlinear fitting using function value only | |
| lsfit_d_nlfb | Bound contstrained nonlinear fitting using function value only | |
| lsfit_d_nlfg | Nonlinear fitting using gradient | |
| lsfit_d_nlscale | Nonlinear fitting with custom scaling and bound constraints | |
| lsfit_d_pol | Unconstrained polynomial fitting | |
| lsfit_d_polc | Constrained polynomial fitting | |
| lsfit_d_spline | Unconstrained fitting by penalized regression spline | |
| lsfit_t_4pl | 4-parameter logistic fitting | |
| lsfit_t_5pl | 5-parameter logistic fitting |
barycentricfitreport class/************************************************************************* Barycentric fitting report: TerminationType completion code: >0 for success, <0 for failure RMSError RMS error AvgError average error AvgRelError average relative error (for non-zero Y[I]) MaxError maximum error TaskRCond reciprocal of task's condition number *************************************************************************/class barycentricfitreport { public: barycentricfitreport(); barycentricfitreport(const barycentricfitreport &rhs); barycentricfitreport& operator=(const barycentricfitreport &rhs); virtual ~barycentricfitreport(); ae_int_t terminationtype; double taskrcond; ae_int_t dbest; double rmserror; double avgerror; double avgrelerror; double maxerror; };
lsfitreport class/************************************************************************* Least squares fitting report. This structure contains informational fields which are set by fitting functions provided by this unit. Different functions initialize different sets of fields, so you should read documentation on specific function you used in order to know which fields are initialized. TerminationType filled by all solvers: * positive values, usually 1, denote success * negative values denote various failure scenarios TaskRCond reciprocal of task's condition number IterationsCount number of internal iterations VarIdx if user-supplied gradient contains errors which were detected by nonlinear fitter, this field is set to index of the first component of gradient which is suspected to be spoiled by bugs. RMSError RMS error AvgError average error AvgRelError average relative error (for non-zero Y[I]) MaxError maximum error WRMSError weighted RMS error CovPar covariance matrix for parameters, filled by some solvers ErrPar vector of errors in parameters, filled by some solvers ErrCurve vector of fit errors - variability of the best-fit curve, filled by some solvers. Noise vector of per-point noise estimates, filled by some solvers. R2 coefficient of determination (non-weighted, non-adjusted), filled by some solvers. *************************************************************************/class lsfitreport { public: lsfitreport(); lsfitreport(const lsfitreport &rhs); lsfitreport& operator=(const lsfitreport &rhs); virtual ~lsfitreport(); ae_int_t terminationtype; double taskrcond; ae_int_t iterationscount; ae_int_t varidx; double rmserror; double avgerror; double avgrelerror; double maxerror; double wrmserror; real_2d_array covpar; real_1d_array errpar; real_1d_array errcurve; real_1d_array noise; double r2; };
lsfitstate class/************************************************************************* Nonlinear fitter. You should use ALGLIB functions to work with fitter. Never try to access its fields directly! *************************************************************************/class lsfitstate { public: lsfitstate(); lsfitstate(const lsfitstate &rhs); lsfitstate& operator=(const lsfitstate &rhs); virtual ~lsfitstate(); };
polynomialfitreport class/************************************************************************* Polynomial fitting report: TerminationType completion code: >0 for success, <0 for failure TaskRCond reciprocal of task's condition number RMSError RMS error AvgError average error AvgRelError average relative error (for non-zero Y[I]) MaxError maximum error *************************************************************************/class polynomialfitreport { public: polynomialfitreport(); polynomialfitreport(const polynomialfitreport &rhs); polynomialfitreport& operator=(const polynomialfitreport &rhs); virtual ~polynomialfitreport(); ae_int_t terminationtype; double taskrcond; double rmserror; double avgerror; double avgrelerror; double maxerror; };
barycentricfitfloaterhormann function/************************************************************************* Rational least squares fitting using Floater-Hormann rational functions with optimal D chosen from [0,9]. Equidistant grid with M node on [min(x),max(x)] is used to build basis functions. Different values of D are tried, optimal D (least root mean square error) is chosen. Task is linear, so linear least squares solver is used. Complexity of this computational scheme is O(N*M^2) (mostly dominated by the least squares solver). INPUT PARAMETERS: X - points, array[0..N-1]. Y - function values, array[0..N-1]. N - number of points, N>0. M - number of basis functions ( = number_of_nodes), M>=2. OUTPUT PARAMETERS: B - barycentric interpolant. Rep - fitting report. The following fields are set: * Rep.TerminationType is a completion code, always set to 1 * DBest best value of the D parameter * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB PROJECT -- Copyright 18.08.2009 by Bochkanov Sergey *************************************************************************/void barycentricfitfloaterhormann(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const ae_int_t m, barycentricinterpolant &b, barycentricfitreport &rep, const xparams _xparams = alglib::xdefault);
barycentricfitfloaterhormannwc function/************************************************************************* Weghted rational least squares fitting using Floater-Hormann rational functions with optimal D chosen from [0,9], with constraints and individual weights. Equidistant grid with M node on [min(x),max(x)] is used to build basis functions. Different values of D are tried, optimal D (least WEIGHTED root mean square error) is chosen. Task is linear, so linear least squares solver is used. Complexity of this computational scheme is O(N*M^2) (mostly dominated by the least squares solver). SEE ALSO * BarycentricFitFloaterHormann(), "lightweight" fitting without invididual weights and constraints. INPUT PARAMETERS: X - points, array[0..N-1]. Y - function values, array[0..N-1]. W - weights, array[0..N-1] Each summand in square sum of approximation deviations from given values is multiplied by the square of corresponding weight. Fill it by 1's if you don't want to solve weighted task. N - number of points, N>0. XC - points where function values/derivatives are constrained, array[0..K-1]. YC - values of constraints, array[0..K-1] DC - array[0..K-1], types of constraints: * DC[i]=0 means that S(XC[i])=YC[i] * DC[i]=1 means that S'(XC[i])=YC[i] SEE BELOW FOR IMPORTANT INFORMATION ON CONSTRAINTS K - number of constraints, 0<=K<M. K=0 means no constraints (XC/YC/DC are not used in such cases) M - number of basis functions ( = number_of_nodes), M>=2. OUTPUT PARAMETERS: B - barycentric interpolant. Undefined for rep.terminationtype<0. Rep - fitting report. The following fields are set: * Rep.TerminationType is a completion code: * set to 1 on success * set to -3 on failure due to problematic constraints: either too many constraints, degenerate constraints or inconsistent constraints were passed * DBest best value of the D parameter * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED IMPORTANT: this subroutine doesn't calculate task's condition number for K<>0. SETTING CONSTRAINTS - DANGERS AND OPPORTUNITIES: Setting constraints can lead to undesired results, like ill-conditioned behavior, or inconsistency being detected. From the other side, it allows us to improve quality of the fit. Here we summarize our experience with constrained barycentric interpolants: * excessive constraints can be inconsistent. Floater-Hormann basis functions aren't as flexible as splines (although they are very smooth). * the more evenly constraints are spread across [min(x),max(x)], the more chances that they will be consistent * the greater is M (given fixed constraints), the more chances that constraints will be consistent * in the general case, consistency of constraints IS NOT GUARANTEED. * in the several special cases, however, we CAN guarantee consistency. * one of this cases is constraints on the function VALUES at the interval boundaries. Note that consustency of the constraints on the function DERIVATIVES is NOT guaranteed (you can use in such cases cubic splines which are more flexible). * another special case is ONE constraint on the function value (OR, but not AND, derivative) anywhere in the interval Our final recommendation is to use constraints WHEN AND ONLY WHEN you can't solve your task without them. Anything beyond special cases given above is not guaranteed and may result in inconsistency. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB PROJECT -- Copyright 18.08.2009 by Bochkanov Sergey *************************************************************************/void barycentricfitfloaterhormannwc(const real_1d_array &x, const real_1d_array &y, const real_1d_array &w, const ae_int_t n, const real_1d_array &xc, const real_1d_array &yc, const integer_1d_array &dc, const ae_int_t k, const ae_int_t m, barycentricinterpolant &b, barycentricfitreport &rep, const xparams _xparams = alglib::xdefault);
logisticcalc4 function/************************************************************************* This function calculates value of four-parameter logistic (4PL) model at specified point X. 4PL model has following form: F(x|A,B,C,D) = D+(A-D)/(1+Power(x/C,B)) INPUT PARAMETERS: X - current point, X>=0: * zero X is correctly handled even for B<=0 * negative X results in exception. A, B, C, D- parameters of 4PL model: * A is unconstrained * B is unconstrained; zero or negative values are handled correctly. * C>0, non-positive value results in exception * D is unconstrained RESULT: model value at X NOTE: if B=0, denominator is assumed to be equal to 2.0 even for zero X (strictly speaking, 0^0 is undefined). NOTE: this function also throws exception if all input parameters are correct, but overflow was detected during calculations. NOTE: this function performs a lot of checks; if you need really high performance, consider evaluating model yourself, without checking for degenerate cases. -- ALGLIB PROJECT -- Copyright 14.05.2014 by Bochkanov Sergey *************************************************************************/double logisticcalc4(const double x, const double a, const double b, const double c, const double d, const xparams _xparams = alglib::xdefault);
Examples: [1]
logisticcalc5 function/************************************************************************* This function calculates value of five-parameter logistic (5PL) model at specified point X. 5PL model has following form: F(x|A,B,C,D,G) = D+(A-D)/Power(1+Power(x/C,B),G) INPUT PARAMETERS: X - current point, X>=0: * zero X is correctly handled even for B<=0 * negative X results in exception. A, B, C, D, G- parameters of 5PL model: * A is unconstrained * B is unconstrained; zero or negative values are handled correctly. * C>0, non-positive value results in exception * D is unconstrained * G>0, non-positive value results in exception RESULT: model value at X NOTE: if B=0, denominator is assumed to be equal to Power(2.0,G) even for zero X (strictly speaking, 0^0 is undefined). NOTE: this function also throws exception if all input parameters are correct, but overflow was detected during calculations. NOTE: this function performs a lot of checks; if you need really high performance, consider evaluating model yourself, without checking for degenerate cases. -- ALGLIB PROJECT -- Copyright 14.05.2014 by Bochkanov Sergey *************************************************************************/double logisticcalc5(const double x, const double a, const double b, const double c, const double d, const double g, const xparams _xparams = alglib::xdefault);
Examples: [1]
logisticfit4 function/************************************************************************* This function fits four-parameter logistic (4PL) model to data provided by user. 4PL model has following form: F(x|A,B,C,D) = D+(A-D)/(1+Power(x/C,B)) Here: * A, D - unconstrained (see LogisticFit4EC() for constrained 4PL) * B>=0 * C>0 IMPORTANT: output of this function is constrained in such way that B>0. Because 4PL model is symmetric with respect to B, there is no need to explore B<0. Constraining B makes algorithm easier to stabilize and debug. Users who for some reason prefer to work with negative B's should transform output themselves (swap A and D, replace B by -B). 4PL fitting is implemented as follows: * we perform small number of restarts from random locations which helps to solve problem of bad local extrema. Locations are only partially random - we use input data to determine good initial guess, but we include controlled amount of randomness. * we perform Levenberg-Marquardt fitting with very tight constraints on parameters B and C - it allows us to find good initial guess for the second stage without risk of running into "flat spot". * second Levenberg-Marquardt round is performed without excessive constraints. Results from the previous round are used as initial guess. * after fitting is done, we compare results with best values found so far, rewrite "best solution" if needed, and move to next random location. Overall algorithm is very stable and is not prone to bad local extrema. Furthermore, it automatically scales when input data have very large or very small range. INPUT PARAMETERS: X - array[N], stores X-values. MUST include only non-negative numbers (but may include zero values). Can be unsorted. Y - array[N], values to fit. N - number of points. If N is less than length of X/Y, only leading N elements are used. OUTPUT PARAMETERS: A, B, C, D- parameters of 4PL model Rep - fitting report. This structure has many fields, but ONLY ONES LISTED BELOW ARE SET: * Rep.IterationsCount - number of iterations performed * Rep.RMSError - root-mean-square error * Rep.AvgError - average absolute error * Rep.AvgRelError - average relative error (calculated for non-zero Y-values) * Rep.MaxError - maximum absolute error * Rep.R2 - coefficient of determination, R-squared. This coefficient is calculated as R2=1-RSS/TSS (in case of nonlinear regression there are multiple ways to define R2, each of them giving different results). NOTE: for stability reasons the B parameter is restricted by [1/1000,1000] range. It prevents algorithm from making trial steps deep into the area of bad parameters. NOTE: after you obtained coefficients, you can evaluate model with LogisticCalc4() function. NOTE: if you need better control over fitting process than provided by this function, you may use LogisticFit45X(). NOTE: step is automatically scaled according to scale of parameters being fitted before we compare its length with EpsX. Thus, this function can be used to fit data with very small or very large values without changing EpsX. -- ALGLIB PROJECT -- Copyright 14.02.2014 by Bochkanov Sergey *************************************************************************/void logisticfit4(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, double &a, double &b, double &c, double &d, lsfitreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
logisticfit45x function/************************************************************************* This is "expert" 4PL/5PL fitting function, which can be used if you need better control over fitting process than provided by LogisticFit4() or LogisticFit5(). This function fits model of the form F(x|A,B,C,D) = D+(A-D)/(1+Power(x/C,B)) (4PL model) or F(x|A,B,C,D,G) = D+(A-D)/Power(1+Power(x/C,B),G) (5PL model) Here: * A, D - unconstrained * B>=0 for 4PL, unconstrained for 5PL * C>0 * G>0 (if present) INPUT PARAMETERS: X - array[N], stores X-values. MUST include only non-negative numbers (but may include zero values). Can be unsorted. Y - array[N], values to fit. N - number of points. If N is less than length of X/Y, only leading N elements are used. CnstrLeft- optional equality constraint for model value at the left boundary (at X=0). Specify NAN (Not-a-Number) if you do not need constraint on the model value at X=0 (in C++ you can pass alglib::fp_nan as parameter, in C# it will be Double.NaN). See below, section "EQUALITY CONSTRAINTS" for more information about constraints. CnstrRight- optional equality constraint for model value at X=infinity. Specify NAN (Not-a-Number) if you do not need constraint on the model value (in C++ you can pass alglib::fp_nan as parameter, in C# it will be Double.NaN). See below, section "EQUALITY CONSTRAINTS" for more information about constraints. Is4PL - whether 4PL or 5PL models are fitted LambdaV - regularization coefficient, LambdaV>=0. Set it to zero unless you know what you are doing. EpsX - stopping condition (step size), EpsX>=0. Zero value means that small step is automatically chosen. See notes below for more information. RsCnt - number of repeated restarts from random points. 4PL/5PL models are prone to problem of bad local extrema. Utilizing multiple random restarts allows us to improve algorithm convergence. RsCnt>=0. Zero value means that function automatically choose small amount of restarts (recommended). OUTPUT PARAMETERS: A, B, C, D- parameters of 4PL model G - parameter of 5PL model; for Is4PL=True, G=1 is returned. Rep - fitting report. This structure has many fields, but ONLY ONES LISTED BELOW ARE SET: * Rep.IterationsCount - number of iterations performed * Rep.RMSError - root-mean-square error * Rep.AvgError - average absolute error * Rep.AvgRelError - average relative error (calculated for non-zero Y-values) * Rep.MaxError - maximum absolute error * Rep.R2 - coefficient of determination, R-squared. This coefficient is calculated as R2=1-RSS/TSS (in case of nonlinear regression there are multiple ways to define R2, each of them giving different results). NOTE: for better stability B parameter is restricted by [+-1/1000,+-1000] range, and G is restricted by [1/10,10] range. It prevents algorithm from making trial steps deep into the area of bad parameters. NOTE: after you obtained coefficients, you can evaluate model with LogisticCalc5() function. NOTE: step is automatically scaled according to scale of parameters being fitted before we compare its length with EpsX. Thus, this function can be used to fit data with very small or very large values without changing EpsX. EQUALITY CONSTRAINTS ON PARAMETERS 4PL/5PL solver supports equality constraints on model values at the left boundary (X=0) and right boundary (X=infinity). These constraints are completely optional and you can specify both of them, only one - or no constraints at all. Parameter CnstrLeft contains left constraint (or NAN for unconstrained fitting), and CnstrRight contains right one. For 4PL, left constraint ALWAYS corresponds to parameter A, and right one is ALWAYS constraint on D. That's because 4PL model is normalized in such way that B>=0. For 5PL model things are different. Unlike 4PL one, 5PL model is NOT symmetric with respect to change in sign of B. Thus, negative B's are possible, and left constraint may constrain parameter A (for positive B's) - or parameter D (for negative B's). Similarly changes meaning of right constraint. You do not have to decide what parameter to constrain - algorithm will automatically determine correct parameters as fitting progresses. However, question highlighted above is important when you interpret fitting results. -- ALGLIB PROJECT -- Copyright 14.02.2014 by Bochkanov Sergey *************************************************************************/void logisticfit45x(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const double cnstrleft, const double cnstrright, const bool is4pl, const double lambdav, const double epsx, const ae_int_t rscnt, double &a, double &b, double &c, double &d, double &g, lsfitreport &rep, const xparams _xparams = alglib::xdefault);
logisticfit4ec function/************************************************************************* This function fits four-parameter logistic (4PL) model to data provided by user, with optional constraints on parameters A and D. 4PL model has following form: F(x|A,B,C,D) = D+(A-D)/(1+Power(x/C,B)) Here: * A, D - with optional equality constraints * B>=0 * C>0 IMPORTANT: output of this function is constrained in such way that B>0. Because 4PL model is symmetric with respect to B, there is no need to explore B<0. Constraining B makes algorithm easier to stabilize and debug. Users who for some reason prefer to work with negative B's should transform output themselves (swap A and D, replace B by -B). 4PL fitting is implemented as follows: * we perform small number of restarts from random locations which helps to solve problem of bad local extrema. Locations are only partially random - we use input data to determine good initial guess, but we include controlled amount of randomness. * we perform Levenberg-Marquardt fitting with very tight constraints on parameters B and C - it allows us to find good initial guess for the second stage without risk of running into "flat spot". * second Levenberg-Marquardt round is performed without excessive constraints. Results from the previous round are used as initial guess. * after fitting is done, we compare results with best values found so far, rewrite "best solution" if needed, and move to next random location. Overall algorithm is very stable and is not prone to bad local extrema. Furthermore, it automatically scales when input data have very large or very small range. INPUT PARAMETERS: X - array[N], stores X-values. MUST include only non-negative numbers (but may include zero values). Can be unsorted. Y - array[N], values to fit. N - number of points. If N is less than length of X/Y, only leading N elements are used. CnstrLeft- optional equality constraint for model value at the left boundary (at X=0). Specify NAN (Not-a-Number) if you do not need constraint on the model value at X=0 (in C++ you can pass alglib::fp_nan as parameter, in C# it will be Double.NaN). See below, section "EQUALITY CONSTRAINTS" for more information about constraints. CnstrRight- optional equality constraint for model value at X=infinity. Specify NAN (Not-a-Number) if you do not need constraint on the model value (in C++ you can pass alglib::fp_nan as parameter, in C# it will be Double.NaN). See below, section "EQUALITY CONSTRAINTS" for more information about constraints. OUTPUT PARAMETERS: A, B, C, D- parameters of 4PL model Rep - fitting report. This structure has many fields, but ONLY ONES LISTED BELOW ARE SET: * Rep.IterationsCount - number of iterations performed * Rep.RMSError - root-mean-square error * Rep.AvgError - average absolute error * Rep.AvgRelError - average relative error (calculated for non-zero Y-values) * Rep.MaxError - maximum absolute error * Rep.R2 - coefficient of determination, R-squared. This coefficient is calculated as R2=1-RSS/TSS (in case of nonlinear regression there are multiple ways to define R2, each of them giving different results). NOTE: for stability reasons the B parameter is restricted by [1/1000,1000] range. It prevents algorithm from making trial steps deep into the area of bad parameters. NOTE: after you obtained coefficients, you can evaluate model with LogisticCalc4() function. NOTE: if you need better control over fitting process than provided by this function, you may use LogisticFit45X(). NOTE: step is automatically scaled according to scale of parameters being fitted before we compare its length with EpsX. Thus, this function can be used to fit data with very small or very large values without changing EpsX. EQUALITY CONSTRAINTS ON PARAMETERS 4PL/5PL solver supports equality constraints on model values at the left boundary (X=0) and right boundary (X=infinity). These constraints are completely optional and you can specify both of them, only one - or no constraints at all. Parameter CnstrLeft contains left constraint (or NAN for unconstrained fitting), and CnstrRight contains right one. For 4PL, left constraint ALWAYS corresponds to parameter A, and right one is ALWAYS constraint on D. That's because 4PL model is normalized in such way that B>=0. -- ALGLIB PROJECT -- Copyright 14.02.2014 by Bochkanov Sergey *************************************************************************/void logisticfit4ec(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const double cnstrleft, const double cnstrright, double &a, double &b, double &c, double &d, lsfitreport &rep, const xparams _xparams = alglib::xdefault);
logisticfit5 function/************************************************************************* This function fits five-parameter logistic (5PL) model to data provided by user. 5PL model has following form: F(x|A,B,C,D,G) = D+(A-D)/Power(1+Power(x/C,B),G) Here: * A, D - unconstrained * B - unconstrained * C>0 * G>0 IMPORTANT: unlike in 4PL fitting, output of this function is NOT constrained in such way that B is guaranteed to be positive. Furthermore, unlike 4PL, 5PL model is NOT symmetric with respect to B, so you can NOT transform model to equivalent one, with B having desired sign (>0 or <0). 5PL fitting is implemented as follows: * we perform small number of restarts from random locations which helps to solve problem of bad local extrema. Locations are only partially random - we use input data to determine good initial guess, but we include controlled amount of randomness. * we perform Levenberg-Marquardt fitting with very tight constraints on parameters B and C - it allows us to find good initial guess for the second stage without risk of running into "flat spot". Parameter G is fixed at G=1. * second Levenberg-Marquardt round is performed without excessive constraints on B and C, but with G still equal to 1. Results from the previous round are used as initial guess. * third Levenberg-Marquardt round relaxes constraints on G and tries two different models - one with B>0 and one with B<0. * after fitting is done, we compare results with best values found so far, rewrite "best solution" if needed, and move to next random location. Overall algorithm is very stable and is not prone to bad local extrema. Furthermore, it automatically scales when input data have very large or very small range. INPUT PARAMETERS: X - array[N], stores X-values. MUST include only non-negative numbers (but may include zero values). Can be unsorted. Y - array[N], values to fit. N - number of points. If N is less than length of X/Y, only leading N elements are used. OUTPUT PARAMETERS: A,B,C,D,G- parameters of 5PL model Rep - fitting report. This structure has many fields, but ONLY ONES LISTED BELOW ARE SET: * Rep.IterationsCount - number of iterations performed * Rep.RMSError - root-mean-square error * Rep.AvgError - average absolute error * Rep.AvgRelError - average relative error (calculated for non-zero Y-values) * Rep.MaxError - maximum absolute error * Rep.R2 - coefficient of determination, R-squared. This coefficient is calculated as R2=1-RSS/TSS (in case of nonlinear regression there are multiple ways to define R2, each of them giving different results). NOTE: for better stability B parameter is restricted by [+-1/1000,+-1000] range, and G is restricted by [1/10,10] range. It prevents algorithm from making trial steps deep into the area of bad parameters. NOTE: after you obtained coefficients, you can evaluate model with LogisticCalc5() function. NOTE: if you need better control over fitting process than provided by this function, you may use LogisticFit45X(). NOTE: step is automatically scaled according to scale of parameters being fitted before we compare its length with EpsX. Thus, this function can be used to fit data with very small or very large values without changing EpsX. -- ALGLIB PROJECT -- Copyright 14.02.2014 by Bochkanov Sergey *************************************************************************/void logisticfit5(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, double &a, double &b, double &c, double &d, double &g, lsfitreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
logisticfit5ec function/************************************************************************* This function fits five-parameter logistic (5PL) model to data provided by user, subject to optional equality constraints on parameters A and D. 5PL model has following form: F(x|A,B,C,D,G) = D+(A-D)/Power(1+Power(x/C,B),G) Here: * A, D - with optional equality constraints * B - unconstrained * C>0 * G>0 IMPORTANT: unlike in 4PL fitting, output of this function is NOT constrained in such way that B is guaranteed to be positive. Furthermore, unlike 4PL, 5PL model is NOT symmetric with respect to B, so you can NOT transform model to equivalent one, with B having desired sign (>0 or <0). 5PL fitting is implemented as follows: * we perform small number of restarts from random locations which helps to solve problem of bad local extrema. Locations are only partially random - we use input data to determine good initial guess, but we include controlled amount of randomness. * we perform Levenberg-Marquardt fitting with very tight constraints on parameters B and C - it allows us to find good initial guess for the second stage without risk of running into "flat spot". Parameter G is fixed at G=1. * second Levenberg-Marquardt round is performed without excessive constraints on B and C, but with G still equal to 1. Results from the previous round are used as initial guess. * third Levenberg-Marquardt round relaxes constraints on G and tries two different models - one with B>0 and one with B<0. * after fitting is done, we compare results with best values found so far, rewrite "best solution" if needed, and move to next random location. Overall algorithm is very stable and is not prone to bad local extrema. Furthermore, it automatically scales when input data have very large or very small range. INPUT PARAMETERS: X - array[N], stores X-values. MUST include only non-negative numbers (but may include zero values). Can be unsorted. Y - array[N], values to fit. N - number of points. If N is less than length of X/Y, only leading N elements are used. CnstrLeft- optional equality constraint for model value at the left boundary (at X=0). Specify NAN (Not-a-Number) if you do not need constraint on the model value at X=0 (in C++ you can pass alglib::fp_nan as parameter, in C# it will be Double.NaN). See below, section "EQUALITY CONSTRAINTS" for more information about constraints. CnstrRight- optional equality constraint for model value at X=infinity. Specify NAN (Not-a-Number) if you do not need constraint on the model value (in C++ you can pass alglib::fp_nan as parameter, in C# it will be Double.NaN). See below, section "EQUALITY CONSTRAINTS" for more information about constraints. OUTPUT PARAMETERS: A,B,C,D,G- parameters of 5PL model Rep - fitting report. This structure has many fields, but ONLY ONES LISTED BELOW ARE SET: * Rep.IterationsCount - number of iterations performed * Rep.RMSError - root-mean-square error * Rep.AvgError - average absolute error * Rep.AvgRelError - average relative error (calculated for non-zero Y-values) * Rep.MaxError - maximum absolute error * Rep.R2 - coefficient of determination, R-squared. This coefficient is calculated as R2=1-RSS/TSS (in case of nonlinear regression there are multiple ways to define R2, each of them giving different results). NOTE: for better stability B parameter is restricted by [+-1/1000,+-1000] range, and G is restricted by [1/10,10] range. It prevents algorithm from making trial steps deep into the area of bad parameters. NOTE: after you obtained coefficients, you can evaluate model with LogisticCalc5() function. NOTE: if you need better control over fitting process than provided by this function, you may use LogisticFit45X(). NOTE: step is automatically scaled according to scale of parameters being fitted before we compare its length with EpsX. Thus, this function can be used to fit data with very small or very large values without changing EpsX. EQUALITY CONSTRAINTS ON PARAMETERS 5PL solver supports equality constraints on model values at the left boundary (X=0) and right boundary (X=infinity). These constraints are completely optional and you can specify both of them, only one - or no constraints at all. Parameter CnstrLeft contains left constraint (or NAN for unconstrained fitting), and CnstrRight contains right one. Unlike 4PL one, 5PL model is NOT symmetric with respect to change in sign of B. Thus, negative B's are possible, and left constraint may constrain parameter A (for positive B's) - or parameter D (for negative B's). Similarly changes meaning of right constraint. You do not have to decide what parameter to constrain - algorithm will automatically determine correct parameters as fitting progresses. However, question highlighted above is important when you interpret fitting results. -- ALGLIB PROJECT -- Copyright 14.02.2014 by Bochkanov Sergey *************************************************************************/void logisticfit5ec(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const double cnstrleft, const double cnstrright, double &a, double &b, double &c, double &d, double &g, lsfitreport &rep, const xparams _xparams = alglib::xdefault);
lsfitcreatef function/************************************************************************* Nonlinear least squares fitting using function values only. Combination of numerical differentiation and secant updates is used to obtain function Jacobian. Nonlinear task min(F(c)) is solved, where F(c) = (f(c,x[0])-y[0])^2 + ... + (f(c,x[n-1])-y[n-1])^2, * N is a number of points, * M is a dimension of a space points belong to, * K is a dimension of a space of parameters being fitted, * w is an N-dimensional vector of weight coefficients, * x is a set of N points, each of them is an M-dimensional vector, * c is a K-dimensional vector of parameters being fitted This subroutine uses only f(c,x[i]). INPUT PARAMETERS: X - array[0..N-1,0..M-1], points (one row = one point) Y - array[0..N-1], function values. C - array[0..K-1], initial approximation to the solution, N - number of points, N>1 M - dimension of space K - number of parameters being fitted DiffStep- numerical differentiation step, >0; Obviously, step size should not be too large in order to get a good numerical derivative. However, it also should not be too small because numerical errors are greatly amplified by numerical differentiation. By default, symmetric 3-point formula which provides good accuracy is used. It can be changed to a faster but less precise 2-point one with minlmsetnumdiff() function. OUTPUT PARAMETERS: State - structure which stores algorithm state IMPORTANT: the LSFIT optimizer supports parallel model evaluation and parallel numerical differentiation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions, greatly accelerates fits with large datasets and/or expensive target functions. Callback parallelism is usually beneficial when a single pass over the entire dataset requires more than several milliseconds. See ALGLIB Reference Manual, 'Working with commercial version' section, and comments on lsfitfit() function for more information. -- ALGLIB -- Copyright 18.10.2008 by Bochkanov Sergey *************************************************************************/void lsfitcreatef(const real_2d_array &x, const real_1d_array &y, const real_1d_array &c, const ae_int_t n, const ae_int_t m, const ae_int_t k, const double diffstep, lsfitstate &state, const xparams _xparams = alglib::xdefault); void lsfitcreatef(const real_2d_array &x, const real_1d_array &y, const real_1d_array &c, const double diffstep, lsfitstate &state, const xparams _xparams = alglib::xdefault);
lsfitcreatefg function/************************************************************************* Nonlinear least squares fitting using gradient only, without individual weights. Nonlinear task min(F(c)) is solved, where F(c) = ((f(c,x[0])-y[0]))^2 + ... + ((f(c,x[n-1])-y[n-1]))^2, * N is a number of points, * M is a dimension of a space points belong to, * K is a dimension of a space of parameters being fitted, * x is a set of N points, each of them is an M-dimensional vector, * c is a K-dimensional vector of parameters being fitted This subroutine uses only f(c,x[i]) and its gradient. INPUT PARAMETERS: X - array[0..N-1,0..M-1], points (one row = one point) Y - array[0..N-1], function values. C - array[0..K-1], initial approximation to the solution, N - number of points, N>1 M - dimension of space K - number of parameters being fitted OUTPUT PARAMETERS: State - structure which stores algorithm state IMPORTANT: the LSFIT optimizer supports parallel model evaluation and parallel numerical differentiation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions, greatly accelerates fits with large datasets and/or expensive target functions. Callback parallelism is usually beneficial when a single pass over the entire dataset requires more than several milliseconds. See ALGLIB Reference Manual, 'Working with commercial version' section, and comments on lsfitfit() function for more information. -- ALGLIB -- Copyright 17.08.2009 by Bochkanov Sergey *************************************************************************/void lsfitcreatefg(const real_2d_array &x, const real_1d_array &y, const real_1d_array &c, const ae_int_t n, const ae_int_t m, const ae_int_t k, lsfitstate &state, const xparams _xparams = alglib::xdefault); void lsfitcreatefg(const real_2d_array &x, const real_1d_array &y, const real_1d_array &c, lsfitstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
lsfitcreatewf function/************************************************************************* Weighted nonlinear least squares fitting using function values only. Combination of numerical differentiation and secant updates is used to obtain function Jacobian. Nonlinear task min(F(c)) is solved, where F(c) = (w[0]*(f(c,x[0])-y[0]))^2 + ... + (w[n-1]*(f(c,x[n-1])-y[n-1]))^2, * N is a number of points, * M is a dimension of a space points belong to, * K is a dimension of a space of parameters being fitted, * w is an N-dimensional vector of weight coefficients, * x is a set of N points, each of them is an M-dimensional vector, * c is a K-dimensional vector of parameters being fitted This subroutine uses only f(c,x[i]). INPUT PARAMETERS: X - array[0..N-1,0..M-1], points (one row = one point) Y - array[0..N-1], function values. W - weights, array[0..N-1] C - array[0..K-1], initial approximation to the solution, N - number of points, N>1 M - dimension of space K - number of parameters being fitted DiffStep- numerical differentiation step, >0; Obviously, step size should not be too large in order to get a good numerical derivative. However, it also should not be too small because numerical errors are greatly amplified by numerical differentiation. By default, symmetric 3-point formula which provides good accuracy is used. It can be changed to a faster but less precise 2-point one with minlmsetnumdiff() function. OUTPUT PARAMETERS: State - structure which stores algorithm state IMPORTANT: the LSFIT optimizer supports parallel model evaluation and parallel numerical differentiation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions, greatly accelerates fits with large datasets and/or expensive target functions. Callback parallelism is usually beneficial when a single pass over the entire dataset requires more than several milliseconds. See ALGLIB Reference Manual, 'Working with commercial version' section, and comments on lsfitfit() function for more information. -- ALGLIB -- Copyright 18.10.2008 by Bochkanov Sergey *************************************************************************/void lsfitcreatewf(const real_2d_array &x, const real_1d_array &y, const real_1d_array &w, const real_1d_array &c, const ae_int_t n, const ae_int_t m, const ae_int_t k, const double diffstep, lsfitstate &state, const xparams _xparams = alglib::xdefault); void lsfitcreatewf(const real_2d_array &x, const real_1d_array &y, const real_1d_array &w, const real_1d_array &c, const double diffstep, lsfitstate &state, const xparams _xparams = alglib::xdefault);
lsfitcreatewfg function/************************************************************************* Weighted nonlinear least squares fitting using gradient only. Nonlinear task min(F(c)) is solved, where F(c) = (w[0]*(f(c,x[0])-y[0]))^2 + ... + (w[n-1]*(f(c,x[n-1])-y[n-1]))^2, * N is a number of points, * M is a dimension of a space points belong to, * K is a dimension of a space of parameters being fitted, * w is an N-dimensional vector of weight coefficients, * x is a set of N points, each of them is an M-dimensional vector, * c is a K-dimensional vector of parameters being fitted This subroutine uses only f(c,x[i]) and its gradient. INPUT PARAMETERS: X - array[0..N-1,0..M-1], points (one row = one point) Y - array[0..N-1], function values. W - weights, array[0..N-1] C - array[0..K-1], initial approximation to the solution, N - number of points, N>1 M - dimension of space K - number of parameters being fitted OUTPUT PARAMETERS: State - structure which stores algorithm state See also: LSFitResults LSFitCreateFG (fitting without weights) LSFitCreateWFGH (fitting using Hessian) IMPORTANT: the LSFIT optimizer supports parallel model evaluation and parallel numerical differentiation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions, greatly accelerates fits with large datasets and/or expensive target functions. Callback parallelism is usually beneficial when a single pass over the entire dataset requires more than several milliseconds. See ALGLIB Reference Manual, 'Working with commercial version' section, and comments on lsfitfit() function for more information. -- ALGLIB -- Copyright 17.08.2009 by Bochkanov Sergey *************************************************************************/void lsfitcreatewfg(const real_2d_array &x, const real_1d_array &y, const real_1d_array &w, const real_1d_array &c, const ae_int_t n, const ae_int_t m, const ae_int_t k, lsfitstate &state, const xparams _xparams = alglib::xdefault); void lsfitcreatewfg(const real_2d_array &x, const real_1d_array &y, const real_1d_array &w, const real_1d_array &c, lsfitstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
lsfitfit function/************************************************************************* This family of functions is used to start iterations of nonlinear fitter These functions accept following parameters: state - algorithm state func - callback which calculates function (or merit function) value func at given point x grad - callback which calculates function (or merit function) value func and gradient grad at given point x rep - optional callback which is called after each iteration can be NULL ptr - optional pointer which is passed to func/grad/hess/jac/rep can be NULL CALLBACK PARALLELISM: The LSFIT optimizer supports parallel model evaluation and parallel numerical differentiation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions, greatly accelerates fits with large datasets and/or expensive target functions. Callback parallelism is usually beneficial when a single pass over the entire dataset requires more than several milliseconds. In this case the job of computing model values at dataset points can be split between multiple threads. If you employ a numerical differentiation scheme, you can also parallelize computation of different components of a numerical gradient. Generally, the mode computationally demanding your problem is (many points, numerical differentiation, expensive model), the more you can get for multithreading. ALGLIB Reference Manual, 'Working with commercial version' section, describes how to activate callback parallelism for your programming language. CALLBACK ARGUMENTS This algorithm is somewhat unusual because it works with parameterized function f(C,X), where X is a function argument (we have many points which are characterized by different argument values), and C is a parameter to fit. For example, if we want to do linear fit by f(c0,c1,x) = c0*x+c1, then x will be argument, and {c0,c1} will be parameters. It is important to understand that this algorithm finds minimum in the space of function PARAMETERS (not arguments), so it needs derivatives of f() with respect to C, not X. In the example above it will need f=c0*x+c1 and {df/dc0,df/dc1} = {x,1} instead of {df/dx} = {c0}. -- ALGLIB -- Copyright 17.12.2023 by Bochkanov Sergey *************************************************************************/void lsfitfit(lsfitstate &state, void (*func)(const real_1d_array &c, const real_1d_array &x, double &func, void *ptr), void (*rep)(const real_1d_array &c, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault); void lsfitfit(lsfitstate &state, void (*func)(const real_1d_array &c, const real_1d_array &x, double &func, void *ptr), void (*grad)(const real_1d_array &c, const real_1d_array &x, double &func, real_1d_array &grad, void *ptr), void (*rep)(const real_1d_array &c, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault);
lsfititeration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool lsfititeration(lsfitstate &state, const xparams _xparams = alglib::xdefault);
lsfitlinear function/************************************************************************* Linear least squares fitting. QR decomposition is used to reduce task to MxM, then triangular solver or SVD-based solver is used depending on condition number of the system. It allows to maximize speed and retain decent accuracy. IMPORTANT: if you want to perform polynomial fitting, it may be more convenient to use PolynomialFit() function. This function gives best results on polynomial problems and solves numerical stability issues which arise when you fit high-degree polynomials to your data. INPUT PARAMETERS: Y - array[0..N-1] Function values in N points. FMatrix - a table of basis functions values, array[0..N-1, 0..M-1]. FMatrix[I, J] - value of J-th basis function in I-th point. N - number of points used. N>=1. M - number of basis functions, M>=1. OUTPUT PARAMETERS: C - decomposition coefficients, array[0..M-1] Rep - fitting report. Following fields are set: * Rep.TerminationType is a completion code, always set to 1 which denotes success * Rep.TaskRCond reciprocal of condition number * R2 non-adjusted coefficient of determination (non-weighted) * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED ERRORS IN PARAMETERS This solver also calculates different kinds of errors in parameters and fills corresponding fields of report: * Rep.CovPar covariance matrix for parameters, array[K,K]. * Rep.ErrPar errors in parameters, array[K], errpar = sqrt(diag(CovPar)) * Rep.ErrCurve vector of fit errors - standard deviations of empirical best-fit curve from "ideal" best-fit curve built with infinite number of samples, array[N]. errcurve = sqrt(diag(F*CovPar*F')), where F is functions matrix. * Rep.Noise vector of per-point estimates of noise, array[N] NOTE: noise in the data is estimated as follows: * for fitting without user-supplied weights all points are assumed to have same level of noise, which is estimated from the data * for fitting with user-supplied weights we assume that noise level in I-th point is inversely proportional to Ith weight. Coefficient of proportionality is estimated from the data. NOTE: we apply small amount of regularization when we invert squared Jacobian and calculate covariance matrix. It guarantees that algorithm won't divide by zero during inversion, but skews error estimates a bit (fractional error is about 10^-9). However, we believe that this difference is insignificant for all practical purposes except for the situation when you want to compare ALGLIB results with "reference" implementation up to the last significant digit. NOTE: covariance matrix is estimated using correction for degrees of freedom (covariances are divided by N-M instead of dividing by N). ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 17.08.2009 by Bochkanov Sergey *************************************************************************/void lsfitlinear(const real_1d_array &y, const real_2d_array &fmatrix, const ae_int_t n, const ae_int_t m, real_1d_array &c, lsfitreport &rep, const xparams _xparams = alglib::xdefault); void lsfitlinear(const real_1d_array &y, const real_2d_array &fmatrix, real_1d_array &c, lsfitreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
lsfitlinearc function/************************************************************************* Constained linear least squares fitting. This is variation of LSFitLinear(), which searchs for min|A*x=b| given that K additional constaints C*x=bc are satisfied. It reduces original task to modified one: min|B*y-d| WITHOUT constraints, then LSFitLinear() is called. IMPORTANT: if you want to perform polynomial fitting, it may be more convenient to use PolynomialFit() function. This function gives best results on polynomial problems and solves numerical stability issues which arise when you fit high-degree polynomials to your data. INPUT PARAMETERS: Y - array[0..N-1] Function values in N points. FMatrix - a table of basis functions values, array[0..N-1, 0..M-1]. FMatrix[I,J] - value of J-th basis function in I-th point. CMatrix - a table of constaints, array[0..K-1,0..M]. I-th row of CMatrix corresponds to I-th linear constraint: CMatrix[I,0]*C[0] + ... + CMatrix[I,M-1]*C[M-1] = CMatrix[I,M] N - number of points used. N>=1. M - number of basis functions, M>=1. K - number of constraints, 0 <= K < M K=0 corresponds to absence of constraints. OUTPUT PARAMETERS: C - decomposition coefficients, array[0..M-1] Rep - fitting report. Following fields are set: * Rep.TerminationType is a completion code: * set to 1 on success * set to -3 on failure due to problematic constraints: either too many constraints (M or more), degenerate constraints (some constraints are repetead twice) or inconsistent constraints are specified * R2 non-adjusted coefficient of determination (non-weighted) * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED IMPORTANT: this subroitine doesn't calculate task's condition number for K<>0. ERRORS IN PARAMETERS This solver also calculates different kinds of errors in parameters and fills corresponding fields of report: * Rep.CovPar covariance matrix for parameters, array[K,K]. * Rep.ErrPar errors in parameters, array[K], errpar = sqrt(diag(CovPar)) * Rep.ErrCurve vector of fit errors - standard deviations of empirical best-fit curve from "ideal" best-fit curve built with infinite number of samples, array[N]. errcurve = sqrt(diag(F*CovPar*F')), where F is functions matrix. * Rep.Noise vector of per-point estimates of noise, array[N] IMPORTANT: errors in parameters are calculated without taking into account boundary/linear constraints! Presence of constraints changes distribution of errors, but there is no easy way to account for constraints when you calculate covariance matrix. NOTE: noise in the data is estimated as follows: * for fitting without user-supplied weights all points are assumed to have same level of noise, which is estimated from the data * for fitting with user-supplied weights we assume that noise level in I-th point is inversely proportional to Ith weight. Coefficient of proportionality is estimated from the data. NOTE: we apply small amount of regularization when we invert squared Jacobian and calculate covariance matrix. It guarantees that algorithm won't divide by zero during inversion, but skews error estimates a bit (fractional error is about 10^-9). However, we believe that this difference is insignificant for all practical purposes except for the situation when you want to compare ALGLIB results with "reference" implementation up to the last significant digit. NOTE: covariance matrix is estimated using correction for degrees of freedom (covariances are divided by N-M instead of dividing by N). ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 07.09.2009 by Bochkanov Sergey *************************************************************************/void lsfitlinearc(const real_1d_array &y, const real_2d_array &fmatrix, const real_2d_array &cmatrix, const ae_int_t n, const ae_int_t m, const ae_int_t k, real_1d_array &c, lsfitreport &rep, const xparams _xparams = alglib::xdefault); void lsfitlinearc(const real_1d_array &y, const real_2d_array &fmatrix, const real_2d_array &cmatrix, real_1d_array &c, lsfitreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
lsfitlinearw function/************************************************************************* Weighted linear least squares fitting. QR decomposition is used to reduce task to MxM, then triangular solver or SVD-based solver is used depending on condition number of the system. It allows to maximize speed and retain decent accuracy. IMPORTANT: if you want to perform polynomial fitting, it may be more convenient to use PolynomialFit() function. This function gives best results on polynomial problems and solves numerical stability issues which arise when you fit high-degree polynomials to your data. INPUT PARAMETERS: Y - array[0..N-1] Function values in N points. W - array[0..N-1] Weights corresponding to function values. Each summand in square sum of approximation deviations from given values is multiplied by the square of corresponding weight. FMatrix - a table of basis functions values, array[0..N-1, 0..M-1]. FMatrix[I, J] - value of J-th basis function in I-th point. N - number of points used. N>=1. M - number of basis functions, M>=1. OUTPUT PARAMETERS: C - decomposition coefficients, array[0..M-1] Rep - fitting report. Following fields are set: * Rep.TerminationType always set to 1 (success) * Rep.TaskRCond reciprocal of condition number * R2 non-adjusted coefficient of determination (non-weighted) * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED ERRORS IN PARAMETERS This solver also calculates different kinds of errors in parameters and fills corresponding fields of report: * Rep.CovPar covariance matrix for parameters, array[K,K]. * Rep.ErrPar errors in parameters, array[K], errpar = sqrt(diag(CovPar)) * Rep.ErrCurve vector of fit errors - standard deviations of empirical best-fit curve from "ideal" best-fit curve built with infinite number of samples, array[N]. errcurve = sqrt(diag(F*CovPar*F')), where F is functions matrix. * Rep.Noise vector of per-point estimates of noise, array[N] NOTE: noise in the data is estimated as follows: * for fitting without user-supplied weights all points are assumed to have same level of noise, which is estimated from the data * for fitting with user-supplied weights we assume that noise level in I-th point is inversely proportional to Ith weight. Coefficient of proportionality is estimated from the data. NOTE: we apply small amount of regularization when we invert squared Jacobian and calculate covariance matrix. It guarantees that algorithm won't divide by zero during inversion, but skews error estimates a bit (fractional error is about 10^-9). However, we believe that this difference is insignificant for all practical purposes except for the situation when you want to compare ALGLIB results with "reference" implementation up to the last significant digit. NOTE: covariance matrix is estimated using correction for degrees of freedom (covariances are divided by N-M instead of dividing by N). ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 17.08.2009 by Bochkanov Sergey *************************************************************************/void lsfitlinearw(const real_1d_array &y, const real_1d_array &w, const real_2d_array &fmatrix, const ae_int_t n, const ae_int_t m, real_1d_array &c, lsfitreport &rep, const xparams _xparams = alglib::xdefault); void lsfitlinearw(const real_1d_array &y, const real_1d_array &w, const real_2d_array &fmatrix, real_1d_array &c, lsfitreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
lsfitlinearwc function/************************************************************************* Weighted constained linear least squares fitting. This is variation of LSFitLinearW(), which searchs for min|A*x=b| given that K additional constaints C*x=bc are satisfied. It reduces original task to modified one: min|B*y-d| WITHOUT constraints, then LSFitLinearW() is called. IMPORTANT: if you want to perform polynomial fitting, it may be more convenient to use PolynomialFit() function. This function gives best results on polynomial problems and solves numerical stability issues which arise when you fit high-degree polynomials to your data. INPUT PARAMETERS: Y - array[0..N-1] Function values in N points. W - array[0..N-1] Weights corresponding to function values. Each summand in square sum of approximation deviations from given values is multiplied by the square of corresponding weight. FMatrix - a table of basis functions values, array[0..N-1, 0..M-1]. FMatrix[I,J] - value of J-th basis function in I-th point. CMatrix - a table of constaints, array[0..K-1,0..M]. I-th row of CMatrix corresponds to I-th linear constraint: CMatrix[I,0]*C[0] + ... + CMatrix[I,M-1]*C[M-1] = CMatrix[I,M] N - number of points used. N>=1. M - number of basis functions, M>=1. K - number of constraints, 0 <= K < M K=0 corresponds to absence of constraints. OUTPUT PARAMETERS: C - decomposition coefficients, array[0..M-1] Rep - fitting report. The following fields are set: * Rep.TerminationType is a completion code: * set to 1 on success * set to -3 on failure due to problematic constraints: either too many constraints (M or more), degenerate constraints (some constraints are repetead twice) or inconsistent constraints are specified * R2 non-adjusted coefficient of determination (non-weighted) * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED IMPORTANT: this subroitine doesn't calculate task's condition number for K<>0. ERRORS IN PARAMETERS This solver also calculates different kinds of errors in parameters and fills corresponding fields of report: * Rep.CovPar covariance matrix for parameters, array[K,K]. * Rep.ErrPar errors in parameters, array[K], errpar = sqrt(diag(CovPar)) * Rep.ErrCurve vector of fit errors - standard deviations of empirical best-fit curve from "ideal" best-fit curve built with infinite number of samples, array[N]. errcurve = sqrt(diag(F*CovPar*F')), where F is functions matrix. * Rep.Noise vector of per-point estimates of noise, array[N] IMPORTANT: errors in parameters are calculated without taking into account boundary/linear constraints! Presence of constraints changes distribution of errors, but there is no easy way to account for constraints when you calculate covariance matrix. NOTE: noise in the data is estimated as follows: * for fitting without user-supplied weights all points are assumed to have same level of noise, which is estimated from the data * for fitting with user-supplied weights we assume that noise level in I-th point is inversely proportional to Ith weight. Coefficient of proportionality is estimated from the data. NOTE: we apply small amount of regularization when we invert squared Jacobian and calculate covariance matrix. It guarantees that algorithm won't divide by zero during inversion, but skews error estimates a bit (fractional error is about 10^-9). However, we believe that this difference is insignificant for all practical purposes except for the situation when you want to compare ALGLIB results with "reference" implementation up to the last significant digit. NOTE: covariance matrix is estimated using correction for degrees of freedom (covariances are divided by N-M instead of dividing by N). ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 07.09.2009 by Bochkanov Sergey *************************************************************************/void lsfitlinearwc(const real_1d_array &y, const real_1d_array &w, const real_2d_array &fmatrix, const real_2d_array &cmatrix, const ae_int_t n, const ae_int_t m, const ae_int_t k, real_1d_array &c, lsfitreport &rep, const xparams _xparams = alglib::xdefault); void lsfitlinearwc(const real_1d_array &y, const real_1d_array &w, const real_2d_array &fmatrix, const real_2d_array &cmatrix, real_1d_array &c, lsfitreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
lsfitresults function/************************************************************************* Nonlinear least squares fitting results. Called after return from LSFitFit(). INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: C - array[K], solution Rep - optimization report. On success following fields are set: * TerminationType completion code: * -8 optimizer detected NAN/INF in the target function and/or gradient * -7 gradient verification failed. See LSFitSetGradientCheck() for more information. * -3 inconsistent constraints * 2 relative step is no more than EpsX. * 5 MaxIts steps was taken * 7 stopping conditions are too stringent, further improvement is impossible * R2 non-adjusted coefficient of determination (non-weighted) * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED * WRMSError weighted rms error on the (X,Y). ERRORS IN PARAMETERS This solver also calculates different kinds of errors in parameters and fills corresponding fields of report: * Rep.CovPar covariance matrix for parameters, array[K,K]. * Rep.ErrPar errors in parameters, array[K], errpar = sqrt(diag(CovPar)) * Rep.ErrCurve vector of fit errors - standard deviations of empirical best-fit curve from "ideal" best-fit curve built with infinite number of samples, array[N]. errcurve = sqrt(diag(J*CovPar*J')), where J is Jacobian matrix. * Rep.Noise vector of per-point estimates of noise, array[N] IMPORTANT: errors in parameters are calculated without taking into account boundary/linear constraints! Presence of constraints changes distribution of errors, but there is no easy way to account for constraints when you calculate covariance matrix. NOTE: noise in the data is estimated as follows: * for fitting without user-supplied weights all points are assumed to have same level of noise, which is estimated from the data * for fitting with user-supplied weights we assume that noise level in I-th point is inversely proportional to Ith weight. Coefficient of proportionality is estimated from the data. NOTE: we apply small amount of regularization when we invert squared Jacobian and calculate covariance matrix. It guarantees that algorithm won't divide by zero during inversion, but skews error estimates a bit (fractional error is about 10^-9). However, we believe that this difference is insignificant for all practical purposes except for the situation when you want to compare ALGLIB results with "reference" implementation up to the last significant digit. NOTE: covariance matrix is estimated using correction for degrees of freedom (covariances are divided by N-M instead of dividing by N). -- ALGLIB -- Copyright 17.08.2009 by Bochkanov Sergey *************************************************************************/void lsfitresults(const lsfitstate &state, real_1d_array &c, lsfitreport &rep, const xparams _xparams = alglib::xdefault);
lsfitsetbc function/************************************************************************* This function sets boundary constraints for underlying optimizer Boundary constraints are inactive by default (after initial creation). They are preserved until explicitly turned off with another SetBC() call. INPUT PARAMETERS: State - structure stores algorithm state BndL - lower bounds, array[K]. If some (all) variables are unbounded, you may specify very small number or -INF (latter is recommended because it will allow solver to use better algorithm). BndU - upper bounds, array[K]. If some (all) variables are unbounded, you may specify very large number or +INF (latter is recommended because it will allow solver to use better algorithm). NOTE 1: it is possible to specify BndL[i]=BndU[i]. In this case I-th variable will be "frozen" at X[i]=BndL[i]=BndU[i]. NOTE 2: unlike other constrained optimization algorithms, this solver has following useful properties: * bound constraints are always satisfied exactly * function is evaluated only INSIDE area specified by bound constraints -- ALGLIB -- Copyright 14.01.2011 by Bochkanov Sergey *************************************************************************/void lsfitsetbc(lsfitstate &state, const real_1d_array &bndl, const real_1d_array &bndu, const xparams _xparams = alglib::xdefault);
lsfitsetcond function/************************************************************************* Stopping conditions for nonlinear least squares fitting. INPUT PARAMETERS: State - structure which stores algorithm state EpsX - >=0 The subroutine finishes its work if on k+1-th iteration the condition |v|<=EpsX is fulfilled, where: * |.| means Euclidian norm * v - scaled step vector, v[i]=dx[i]/s[i] * dx - ste pvector, dx=X(k+1)-X(k) * s - scaling coefficients set by LSFitSetScale() MaxIts - maximum number of iterations. If MaxIts=0, the number of iterations is unlimited. Only Levenberg-Marquardt iterations are counted (L-BFGS/CG iterations are NOT counted because their cost is very low compared to that of LM). NOTE Passing EpsX=0 and MaxIts=0 (simultaneously) will lead to automatic stopping criterion selection (according to the scheme used by MINLM unit). -- ALGLIB -- Copyright 17.08.2009 by Bochkanov Sergey *************************************************************************/void lsfitsetcond(lsfitstate &state, const double epsx, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
lsfitsetgradientcheck function/************************************************************************* This subroutine turns on verification of the user-supplied analytic gradient: * user calls this subroutine before fitting begins * LSFitFit() is called * prior to actual fitting, for each point in data set X_i and each component of parameters being fited C_j algorithm performs following steps: * two trial steps are made to C_j-TestStep*S[j] and C_j+TestStep*S[j], where C_j is j-th parameter and S[j] is a scale of j-th parameter * if needed, steps are bounded with respect to constraints on C[] * F(X_i|C) is evaluated at these trial points * we perform one more evaluation in the middle point of the interval * we build cubic model using function values and derivatives at trial points and we compare its prediction with actual value in the middle point * in case difference between prediction and actual value is higher than some predetermined threshold, algorithm stops with completion code -7; Rep.VarIdx is set to index of the parameter with incorrect derivative. * after verification is over, algorithm proceeds to the actual optimization. NOTE 1: verification needs N*K (points count * parameters count) gradient evaluations. It is very costly and you should use it only for low dimensional problems, when you want to be sure that you've correctly calculated analytic derivatives. You should not use it in the production code (unless you want to check derivatives provided by some third party). NOTE 2: you should carefully choose TestStep. Value which is too large (so large that function behaviour is significantly non-cubic) will lead to false alarms. You may use different step for different parameters by means of setting scale with LSFitSetScale(). NOTE 3: this function may lead to false positives. In case it reports that I-th derivative was calculated incorrectly, you may decrease test step and try one more time - maybe your function changes too sharply and your step is too large for such rapidly chanding function. NOTE 4: this function works only for optimizers created with LSFitCreateWFG() or LSFitCreateFG() constructors. INPUT PARAMETERS: State - structure used to store algorithm state TestStep - verification step: * TestStep=0 turns verification off * TestStep>0 activates verification -- ALGLIB -- Copyright 15.06.2012 by Bochkanov Sergey *************************************************************************/void lsfitsetgradientcheck(lsfitstate &state, const double teststep, const xparams _xparams = alglib::xdefault);
lsfitsetlc function/************************************************************************* This function sets linear constraints for underlying optimizer Linear constraints are inactive by default (after initial creation). They are preserved until explicitly turned off with another SetLC() call. INPUT PARAMETERS: State - structure stores algorithm state C - linear constraints, array[K,N+1]. Each row of C represents one constraint, either equality or inequality (see below): * first N elements correspond to coefficients, * last element corresponds to the right part. All elements of C (including right part) must be finite. CT - type of constraints, array[K]: * if CT[i]>0, then I-th constraint is C[i,*]*x >= C[i,n+1] * if CT[i]=0, then I-th constraint is C[i,*]*x = C[i,n+1] * if CT[i]<0, then I-th constraint is C[i,*]*x <= C[i,n+1] K - number of equality/inequality constraints, K>=0: * if given, only leading K elements of C/CT are used * if not given, automatically determined from sizes of C/CT IMPORTANT: if you have linear constraints, it is strongly recommended to set scale of variables with lsfitsetscale(). QP solver which is used to calculate linearly constrained steps heavily relies on good scaling of input problems. NOTE: linear (non-box) constraints are satisfied only approximately - there always exists some violation due to numerical errors and algorithmic limitations. NOTE: general linear constraints add significant overhead to solution process. Although solver performs roughly same amount of iterations (when compared with similar box-only constrained problem), each iteration now involves solution of linearly constrained QP subproblem, which requires ~3-5 times more Cholesky decompositions. Thus, if you can reformulate your problem in such way this it has only box constraints, it may be beneficial to do so. -- ALGLIB -- Copyright 29.04.2017 by Bochkanov Sergey *************************************************************************/void lsfitsetlc(lsfitstate &state, const real_2d_array &c, const integer_1d_array &ct, const ae_int_t k, const xparams _xparams = alglib::xdefault); void lsfitsetlc(lsfitstate &state, const real_2d_array &c, const integer_1d_array &ct, const xparams _xparams = alglib::xdefault);
lsfitsetnonmonotonicsteps function/************************************************************************* This function is used to activate/deactivate nonmonotonic steps. Such steps may improve convergence on noisy problems or ones with minor smoothness defects. In its standard mode, LSFIT solver compares squared errors f[1] at the trial point with the value at the current point f[0]. Only steps that decrease f() are accepted. When the nonmonotonic mode is activated, f[1] is compared with maximum over several previous locations: max(f[0],f[-1],...,f[-CNT]). We still accept only steps that decrease f(), however our reference value has changed. The net results is that f[1]>f[0] are now allowed. Nonmonotonic steps can help to handle minor defects in the objective (e.g. small noise, discontinuous jumps or nonsmoothness). However, it is important that the overall shape of the problem is still smooth. It may also help to minimize perfectly smooth targets with complex geometries by allowing to jump through curved valleys. However, sometimes nonmonotonic steps degrade convergence by allowing an optimizer to wander too far away from the solution, so this feature should be used only after careful testing. INPUT PARAMETERS: State - structure stores algorithm state Cnt - nonmonotonic memory length, Cnt>=0: * 0 for traditional monotonic steps * 2..3 is recommended for the nonmonotonic optimization -- ALGLIB -- Copyright 07.04.2024 by Bochkanov Sergey *************************************************************************/void lsfitsetnonmonotonicsteps(lsfitstate &state, const ae_int_t cnt, const xparams _xparams = alglib::xdefault);
lsfitsetnumdiff function/************************************************************************* This function sets specific finite difference formula to be used for numerical differentiation. It works only for optimizers configured to use numerical differentiation; in other cases it has no effect. INPUT PARAMETERS: State - optimizer FormulaType - formula type: * 3 for a 3-point formula, which is also known as a symmetric difference quotient (the formula actually uses only two function values per variable: at x+h and x-h). A good choice for medium-accuracy setups, a default option. * 2 for a forward (or backward, depending on variable bounds) finite difference (f(x+h)-f(x))/h. This formula has the lowest accuracy. However, it is 4x faster than the 5-point formula and 2x faster than the 3-point one because, in addition to the central value f(x), it needs only one additional function evaluation per variable. -- ALGLIB -- Copyright 03.12.2024 by Bochkanov Sergey *************************************************************************/void lsfitsetnumdiff(lsfitstate &state, const ae_int_t formulatype, const xparams _xparams = alglib::xdefault);
lsfitsetscale function/************************************************************************* This function sets scaling coefficients for underlying optimizer. ALGLIB optimizers use scaling matrices to test stopping conditions (step size and gradient are scaled before comparison with tolerances). Scale of the I-th variable is a translation invariant measure of: a) "how large" the variable is b) how large the step should be to make significant changes in the function Generally, scale is NOT considered to be a form of preconditioner. But LM optimizer is unique in that it uses scaling matrix both in the stopping condition tests and as Marquardt damping factor. Proper scaling is very important for the algorithm performance. It is less important for the quality of results, but still has some influence (it is easier to converge when variables are properly scaled, so premature stopping is possible when very badly scalled variables are combined with relaxed stopping conditions). INPUT PARAMETERS: State - structure stores algorithm state S - array[N], non-zero scaling coefficients S[i] may be negative, sign doesn't matter. -- ALGLIB -- Copyright 14.01.2011 by Bochkanov Sergey *************************************************************************/void lsfitsetscale(lsfitstate &state, const real_1d_array &s, const xparams _xparams = alglib::xdefault);
Examples: [1]
lsfitsetstpmax function/************************************************************************* This function sets maximum step length INPUT PARAMETERS: State - structure which stores algorithm state StpMax - maximum step length, >=0. Set StpMax to 0.0, if you don't want to limit step length. Use this subroutine when you optimize target function which contains exp() or other fast growing functions, and optimization algorithm makes too large steps which leads to overflow. This function allows us to reject steps that are too large (and therefore expose us to the possible overflow) without actually calculating function value at the x+stp*d. NOTE: non-zero StpMax leads to moderate performance degradation because intermediate step of preconditioned L-BFGS optimization is incompatible with limits on step size. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void lsfitsetstpmax(lsfitstate &state, const double stpmax, const xparams _xparams = alglib::xdefault);
lsfitsetxrep function/************************************************************************* This function turns on/off reporting. INPUT PARAMETERS: State - structure which stores algorithm state NeedXRep- whether iteration reports are needed or not When reports are needed, State.C (current parameters) and State.F (current value of fitting function) are reported. -- ALGLIB -- Copyright 15.08.2010 by Bochkanov Sergey *************************************************************************/void lsfitsetxrep(lsfitstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
lstfitpiecewiselinearrdp function/************************************************************************* This subroutine fits piecewise linear curve to points with Ramer-Douglas- Peucker algorithm, which stops after achieving desired precision. IMPORTANT: * it performs non-least-squares fitting; it builds curve, but this curve does not minimize some least squares metric. See description of RDP algorithm (say, in Wikipedia) for more details on WHAT is performed. * this function does NOT work with parametric curves (i.e. curves which can be represented as {X(t),Y(t)}. It works with curves which can be represented as Y(X). Thus, it is impossible to model figures like circles with this functions. If you want to work with parametric curves, you should use ParametricRDPFixed() function provided by "Parametric" subpackage of "Interpolation" package. INPUT PARAMETERS: X - array of X-coordinates: * at least N elements * can be unordered (points are automatically sorted) * this function may accept non-distinct X (see below for more information on handling of such inputs) Y - array of Y-coordinates: * at least N elements N - number of elements in X/Y Eps - positive number, desired precision. OUTPUT PARAMETERS: X2 - X-values of corner points for piecewise approximation, has length NSections+1 or zero (for NSections=0). Y2 - Y-values of corner points, has length NSections+1 or zero (for NSections=0). NSections- number of sections found by algorithm, NSections can be zero for degenerate datasets (N<=1 or all X[] are non-distinct). NOTE: X2/Y2 are ordered arrays, i.e. (X2[0],Y2[0]) is a first point of curve, (X2[NSection-1],Y2[NSection-1]) is the last point. -- ALGLIB -- Copyright 02.10.2014 by Bochkanov Sergey *************************************************************************/void lstfitpiecewiselinearrdp(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const double eps, real_1d_array &x2, real_1d_array &y2, ae_int_t &nsections, const xparams _xparams = alglib::xdefault);
lstfitpiecewiselinearrdpfixed function/************************************************************************* This subroutine fits piecewise linear curve to points with Ramer-Douglas- Peucker algorithm, which stops after generating specified number of linear sections. IMPORTANT: * it does NOT perform least-squares fitting; it builds curve, but this curve does not minimize some least squares metric. See description of RDP algorithm (say, in Wikipedia) for more details on WHAT is performed. * this function does NOT work with parametric curves (i.e. curves which can be represented as {X(t),Y(t)}. It works with curves which can be represented as Y(X). Thus, it is impossible to model figures like circles with this functions. If you want to work with parametric curves, you should use ParametricRDPFixed() function provided by "Parametric" subpackage of "Interpolation" package. INPUT PARAMETERS: X - array of X-coordinates: * at least N elements * can be unordered (points are automatically sorted) * this function may accept non-distinct X (see below for more information on handling of such inputs) Y - array of Y-coordinates: * at least N elements N - number of elements in X/Y M - desired number of sections: * at most M sections are generated by this function * less than M sections can be generated if we have N<M (or some X are non-distinct). OUTPUT PARAMETERS: X2 - X-values of corner points for piecewise approximation, has length NSections+1 or zero (for NSections=0). Y2 - Y-values of corner points, has length NSections+1 or zero (for NSections=0). NSections- number of sections found by algorithm, NSections<=M, NSections can be zero for degenerate datasets (N<=1 or all X[] are non-distinct). NOTE: X2/Y2 are ordered arrays, i.e. (X2[0],Y2[0]) is a first point of curve, (X2[NSection-1],Y2[NSection-1]) is the last point. -- ALGLIB -- Copyright 02.10.2014 by Bochkanov Sergey *************************************************************************/void lstfitpiecewiselinearrdpfixed(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const ae_int_t m, real_1d_array &x2, real_1d_array &y2, ae_int_t &nsections, const xparams _xparams = alglib::xdefault);
polynomialfit function/************************************************************************* Fitting by polynomials in barycentric form. This function provides simple unterface for unconstrained unweighted fitting. See PolynomialFitWC() if you need constrained fitting. The task is linear, thus the linear least squares solver is used. The complexity of this computational scheme is O(N*M^2), mostly dominated by the least squares solver SEE ALSO: PolynomialFitWC() NOTES: you can convert P from barycentric form to the power or Chebyshev basis with PolynomialBar2Pow() or PolynomialBar2Cheb() functions from POLINT subpackage. INPUT PARAMETERS: X - points, array[0..N-1]. Y - function values, array[0..N-1]. N - number of points, N>0 * if given, only leading N elements of X/Y are used * if not given, automatically determined from sizes of X/Y M - number of basis functions (= polynomial_degree + 1), M>=1 OUTPUT PARAMETERS: P - interpolant in barycentric form for Rep.TerminationType>0. undefined for Rep.TerminationType<0. Rep - fitting report. The following fields are set: * Rep.TerminationType is a completion code which is always set to 1 (success) * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB PROJECT -- Copyright 10.12.2009 by Bochkanov Sergey *************************************************************************/void polynomialfit(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const ae_int_t m, barycentricinterpolant &p, polynomialfitreport &rep, const xparams _xparams = alglib::xdefault); void polynomialfit(const real_1d_array &x, const real_1d_array &y, const ae_int_t m, barycentricinterpolant &p, polynomialfitreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
polynomialfitwc function/************************************************************************* Weighted fitting by polynomials in barycentric form, with constraints on function values or first derivatives. Small regularizing term is used when solving constrained tasks (to improve stability). Task is linear, so linear least squares solver is used. Complexity of this computational scheme is O(N*M^2), mostly dominated by least squares solver SEE ALSO: PolynomialFit() NOTES: you can convert P from barycentric form to the power or Chebyshev basis with PolynomialBar2Pow() or PolynomialBar2Cheb() functions from the POLINT subpackage. INPUT PARAMETERS: X - points, array[0..N-1]. Y - function values, array[0..N-1]. W - weights, array[0..N-1] Each summand in square sum of approximation deviations from given values is multiplied by the square of corresponding weight. Fill it by 1's if you don't want to solve weighted task. N - number of points, N>0. * if given, only leading N elements of X/Y/W are used * if not given, automatically determined from sizes of X/Y/W XC - points where polynomial values/derivatives are constrained, array[0..K-1]. YC - values of constraints, array[0..K-1] DC - array[0..K-1], types of constraints: * DC[i]=0 means that P(XC[i])=YC[i] * DC[i]=1 means that P'(XC[i])=YC[i] SEE BELOW FOR IMPORTANT INFORMATION ON CONSTRAINTS K - number of constraints, 0<=K<M. K=0 means no constraints (XC/YC/DC are not used in such cases) M - number of basis functions (= polynomial_degree + 1), M>=1 OUTPUT PARAMETERS: P - interpolant in barycentric form for Rep.TerminationType>0. undefined for Rep.TerminationType<0. Rep - fitting report. The following fields are set: * Rep.TerminationType is a completion code: * set to 1 on success * set to -3 on failure due to problematic constraints: either too many constraints, degenerate constraints or inconsistent constraints were passed * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED IMPORTANT: this subroitine doesn't calculate task's condition number for K<>0. SETTING CONSTRAINTS - DANGERS AND OPPORTUNITIES: Setting constraints can lead to undesired results, like ill-conditioned behavior, or inconsistency being detected. From the other side, it allows us to improve quality of the fit. Here we summarize our experience with constrained regression splines: * even simple constraints can be inconsistent, see Wikipedia article on this subject: http://en.wikipedia.org/wiki/Birkhoff_interpolation * the greater is M (given fixed constraints), the more chances that constraints will be consistent * in the general case, consistency of constraints is NOT GUARANTEED. * in the one special cases, however, we can guarantee consistency. This case is: M>1 and constraints on the function values (NOT DERIVATIVES) Our final recommendation is to use constraints WHEN AND ONLY when you can't solve your task without them. Anything beyond special cases given above is not guaranteed and may result in inconsistency. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB PROJECT -- Copyright 10.12.2009 by Bochkanov Sergey *************************************************************************/void polynomialfitwc(const real_1d_array &x, const real_1d_array &y, const real_1d_array &w, const ae_int_t n, const real_1d_array &xc, const real_1d_array &yc, const integer_1d_array &dc, const ae_int_t k, const ae_int_t m, barycentricinterpolant &p, polynomialfitreport &rep, const xparams _xparams = alglib::xdefault); void polynomialfitwc(const real_1d_array &x, const real_1d_array &y, const real_1d_array &w, const real_1d_array &xc, const real_1d_array &yc, const integer_1d_array &dc, const ae_int_t m, barycentricinterpolant &p, polynomialfitreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
spline1dfitcubicwc function/************************************************************************* Weighted fitting by cubic spline, with constraints on function values or derivatives. Equidistant grid with M-2 nodes on [min(x,xc),max(x,xc)] is used to build basis functions. Basis functions are cubic splines with continuous second derivatives and non-fixed first derivatives at interval ends. Small regularizing term is used when solving constrained tasks (to improve stability). Task is linear, so linear least squares solver is used. Complexity of this computational scheme is O(N*M^2), mostly dominated by least squares solver IMPORTANT: ALGLIB has a much faster version of the cubic spline fitting function - spline1dfit(). This function performs least squares fit in O(max(M,N)) time/memory. However, it does not support constraints. INPUT PARAMETERS: X - points, array[0..N-1]. Y - function values, array[0..N-1]. W - weights, array[0..N-1] Each summand in square sum of approximation deviations from given values is multiplied by the square of corresponding weight. Fill it by 1's if you don't want to solve weighted task. N - number of points (optional): * N>0 * if given, only first N elements of X/Y/W are processed * if not given, automatically determined from X/Y/W sizes XC - points where spline values/derivatives are constrained, array[0..K-1]. YC - values of constraints, array[0..K-1] DC - array[0..K-1], types of constraints: * DC[i]=0 means that S(XC[i])=YC[i] * DC[i]=1 means that S'(XC[i])=YC[i] SEE BELOW FOR IMPORTANT INFORMATION ON CONSTRAINTS K - number of constraints (optional): * 0<=K<M. * K=0 means no constraints (XC/YC/DC are not used) * if given, only first K elements of XC/YC/DC are used * if not given, automatically determined from XC/YC/DC M - number of basis functions ( = number_of_nodes+2), M>=4. OUTPUT PARAMETERS: S - spline interpolant. Rep - fitting report. The following fields are set: * Rep.TerminationType is a completion code: * set to 1 on success * set to -3 on failure due to problematic constraints: either too many constraints, degenerate constraints or inconsistent constraints were passed * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED IMPORTANT: this subroitine doesn't calculate task's condition number for K<>0. ORDER OF POINTS Subroutine automatically sorts points, so caller may pass unsorted array. SETTING CONSTRAINTS - DANGERS AND OPPORTUNITIES: Setting constraints can lead to undesired results, like ill-conditioned behavior, or inconsistency being detected. From the other side, it allows us to improve quality of the fit. Here we summarize our experience with constrained regression splines: * excessive constraints can be inconsistent. Splines are piecewise cubic functions, and it is easy to create an example, where large number of constraints concentrated in small area will result in inconsistency. Just because spline is not flexible enough to satisfy all of them. And same constraints spread across the [min(x),max(x)] will be perfectly consistent. * the more evenly constraints are spread across [min(x),max(x)], the more chances that they will be consistent * the greater is M (given fixed constraints), the more chances that constraints will be consistent * in the general case, consistency of constraints IS NOT GUARANTEED. * in the several special cases, however, we CAN guarantee consistency. * one of this cases is constraints on the function values AND/OR its derivatives at the interval boundaries. * another special case is ONE constraint on the function value (OR, but not AND, derivative) anywhere in the interval Our final recommendation is to use constraints WHEN AND ONLY WHEN you can't solve your task without them. Anything beyond special cases given above is not guaranteed and may result in inconsistency. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB PROJECT -- Copyright 18.08.2009 by Bochkanov Sergey *************************************************************************/void spline1dfitcubicwc(const real_1d_array &x, const real_1d_array &y, const real_1d_array &w, const ae_int_t n, const real_1d_array &xc, const real_1d_array &yc, const integer_1d_array &dc, const ae_int_t k, const ae_int_t m, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault); void spline1dfitcubicwc(const real_1d_array &x, const real_1d_array &y, const real_1d_array &w, const real_1d_array &xc, const real_1d_array &yc, const integer_1d_array &dc, const ae_int_t m, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault);
spline1dfithermitedeprecated function/************************************************************************* Deprecated fitting function with O(N*M^2+M^3) running time. Superseded by spline1dfit(). -- ALGLIB PROJECT -- Copyright 18.08.2009 by Bochkanov Sergey *************************************************************************/void spline1dfithermitedeprecated(const real_1d_array &x, const real_1d_array &y, const ae_int_t n, const ae_int_t m, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault); void spline1dfithermitedeprecated(const real_1d_array &x, const real_1d_array &y, const ae_int_t m, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault);
spline1dfithermitewc function/************************************************************************* Weighted fitting by Hermite spline, with constraints on function values or first derivatives. Equidistant grid with M nodes on [min(x,xc),max(x,xc)] is used to build basis functions. Basis functions are Hermite splines. Small regularizing term is used when solving constrained tasks (to improve stability). Task is linear, so linear least squares solver is used. Complexity of this computational scheme is O(N*M^2), mostly dominated by least squares solver IMPORTANT: ALGLIB has a much faster version of the cubic spline fitting function - spline1dfit(). This function performs least squares fit in O(max(M,N)) time/memory. However, it does not support constraints. INPUT PARAMETERS: X - points, array[0..N-1]. Y - function values, array[0..N-1]. W - weights, array[0..N-1] Each summand in square sum of approximation deviations from given values is multiplied by the square of corresponding weight. Fill it by 1's if you don't want to solve weighted task. N - number of points (optional): * N>0 * if given, only first N elements of X/Y/W are processed * if not given, automatically determined from X/Y/W sizes XC - points where spline values/derivatives are constrained, array[0..K-1]. YC - values of constraints, array[0..K-1] DC - array[0..K-1], types of constraints: * DC[i]=0 means that S(XC[i])=YC[i] * DC[i]=1 means that S'(XC[i])=YC[i] SEE BELOW FOR IMPORTANT INFORMATION ON CONSTRAINTS K - number of constraints (optional): * 0<=K<M. * K=0 means no constraints (XC/YC/DC are not used) * if given, only first K elements of XC/YC/DC are used * if not given, automatically determined from XC/YC/DC M - number of basis functions (= 2 * number of nodes), M>=4, M IS EVEN! OUTPUT PARAMETERS: S - spline interpolant. Rep - fitting report. The following fields are set: * Rep.TerminationType is a completion code: * set to 1 on success * set to -3 on failure due to problematic constraints: either too many constraints, degenerate constraints or inconsistent constraints were passed * RMSError rms error on the (X,Y). * AvgError average error on the (X,Y). * AvgRelError average relative error on the non-zero Y * MaxError maximum error NON-WEIGHTED ERRORS ARE CALCULATED IMPORTANT: this subroitine doesn't calculate task's condition number for K<>0. IMPORTANT: this subroitine supports only even M's ORDER OF POINTS Subroutine automatically sorts points, so caller may pass unsorted array. SETTING CONSTRAINTS - DANGERS AND OPPORTUNITIES: Setting constraints can lead to undesired results, like ill-conditioned behavior, or inconsistency being detected. From the other side, it allows us to improve quality of the fit. Here we summarize our experience with constrained regression splines: * excessive constraints can be inconsistent. Splines are piecewise cubic functions, and it is easy to create an example, where large number of constraints concentrated in small area will result in inconsistency. Just because spline is not flexible enough to satisfy all of them. And same constraints spread across the [min(x),max(x)] will be perfectly consistent. * the more evenly constraints are spread across [min(x),max(x)], the more chances that they will be consistent * the greater is M (given fixed constraints), the more chances that constraints will be consistent * in the general case, consistency of constraints is NOT GUARANTEED. * in the several special cases, however, we can guarantee consistency. * one of this cases is M>=4 and constraints on the function value (AND/OR its derivative) at the interval boundaries. * another special case is M>=4 and ONE constraint on the function value (OR, BUT NOT AND, derivative) anywhere in [min(x),max(x)] Our final recommendation is to use constraints WHEN AND ONLY when you can't solve your task without them. Anything beyond special cases given above is not guaranteed and may result in inconsistency. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB PROJECT -- Copyright 18.08.2009 by Bochkanov Sergey *************************************************************************/void spline1dfithermitewc(const real_1d_array &x, const real_1d_array &y, const real_1d_array &w, const ae_int_t n, const real_1d_array &xc, const real_1d_array &yc, const integer_1d_array &dc, const ae_int_t k, const ae_int_t m, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault); void spline1dfithermitewc(const real_1d_array &x, const real_1d_array &y, const real_1d_array &w, const real_1d_array &xc, const real_1d_array &yc, const integer_1d_array &dc, const ae_int_t m, spline1dinterpolant &s, spline1dfitreport &rep, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// In this example we demonstrate linear fitting by f(x|a) = a*exp(0.5*x).
//
// We have:
// * y - vector of experimental data
// * fmatrix - matrix of basis functions calculated at sample points
// Actually, we have only one basis function F0 = exp(0.5*x).
//
real_2d_array fmatrix = "[[0.606531],[0.670320],[0.740818],[0.818731],[0.904837],[1.000000],[1.105171],[1.221403],[1.349859],[1.491825],[1.648721]]";
real_1d_array y = "[1.133719, 1.306522, 1.504604, 1.554663, 1.884638, 2.072436, 2.257285, 2.534068, 2.622017, 2.897713, 3.219371]";
real_1d_array c;
lsfitreport rep;
//
// Linear fitting without weights
//
lsfitlinear(y, fmatrix, c, rep);
printf("%s\n", c.tostring(4).c_str()); // EXPECTED: [1.98650]
//
// Linear fitting with individual weights.
// Slightly different result is returned.
//
real_1d_array w = "[1.414213, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]";
lsfitlinearw(y, w, fmatrix, c, rep);
printf("%s\n", c.tostring(4).c_str()); // EXPECTED: [1.983354]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// In this example we demonstrate linear fitting by f(x|a,b) = a*x+b
// with simple constraint f(0)=0.
//
// We have:
// * y - vector of experimental data
// * fmatrix - matrix of basis functions sampled at [0,1] with step 0.2:
// [ 1.0 0.0 ]
// [ 1.0 0.2 ]
// [ 1.0 0.4 ]
// [ 1.0 0.6 ]
// [ 1.0 0.8 ]
// [ 1.0 1.0 ]
// first column contains value of first basis function (constant term)
// second column contains second basis function (linear term)
// * cmatrix - matrix of linear constraints:
// [ 1.0 0.0 0.0 ]
// first two columns contain coefficients before basis functions,
// last column contains desired value of their sum.
// So [1,0,0] means "1*constant_term + 0*linear_term = 0"
//
real_1d_array y = "[0.072436,0.246944,0.491263,0.522300,0.714064,0.921929]";
real_2d_array fmatrix = "[[1,0.0],[1,0.2],[1,0.4],[1,0.6],[1,0.8],[1,1.0]]";
real_2d_array cmatrix = "[[1,0,0]]";
real_1d_array c;
lsfitreport rep;
//
// Constrained fitting without weights
//
lsfitlinearc(y, fmatrix, cmatrix, c, rep);
printf("%s\n", c.tostring(3).c_str()); // EXPECTED: [0,0.932933]
//
// Constrained fitting with individual weights
//
real_1d_array w = "[1, 1.414213, 1, 1, 1, 1]";
lsfitlinearwc(y, w, fmatrix, cmatrix, c, rep);
printf("%s\n", c.tostring(3).c_str()); // EXPECTED: [0,0.938322]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
void function_cx_1_func(const real_1d_array &c, const real_1d_array &x, double &func, void *ptr)
{
// this callback calculates f(c,x)=exp(-c0*sqr(x0))
// where x is a position on X-axis and c is adjustable parameter
func = exp(-c[0]*pow(x[0],2));
}
int main(int argc, char **argv)
{
try
{
//
// In this example we demonstrate exponential fitting by
//
// f(x) = exp(-c*x^2)
//
// using numerical differentiation.
//
// IMPORTANT: the LSFIT optimizer supports parallel model evaluation and
// parallel numerical differentiation ('callback parallelism').
// This feature, which is present in commercial ALGLIB editions
// greatly accelerates fits with large datasets and/or
// expensive target functions.
//
// Callback parallelism is usually beneficial when a single
// pass over the entire dataset requires more than several
// milliseconds. This particular example, of course, is not
// suited for callback parallelism.
//
// See ALGLIB Reference Manual, 'Working with commercial version'
// section, and comments on lsfitfit() function for more
// information.
//
real_2d_array x = "[[-1],[-0.8],[-0.6],[-0.4],[-0.2],[0],[0.2],[0.4],[0.6],[0.8],[1.0]]";
real_1d_array y = "[0.223130, 0.382893, 0.582748, 0.786628, 0.941765, 1.000000, 0.941765, 0.786628, 0.582748, 0.382893, 0.223130]";
real_1d_array c = "[0.3]";
double epsx = 0.000001;
ae_int_t maxits = 0;
lsfitstate state;
lsfitreport rep;
double diffstep = 0.0001;
//
// Fitting without weights
//
lsfitcreatef(x, y, c, diffstep, state);
lsfitsetcond(state, epsx, maxits);
alglib::lsfitfit(state, function_cx_1_func);
lsfitresults(state, c, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 2
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [1.5]
//
// Fitting with weights
// (you can change weights and see how it changes result)
//
real_1d_array w = "[1,1,1,1,1,1,1,1,1,1,1]";
lsfitcreatewf(x, y, w, c, diffstep, state);
lsfitsetcond(state, epsx, maxits);
alglib::lsfitfit(state, function_cx_1_func);
lsfitresults(state, c, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 2
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [1.5]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
void function_cx_1_func(const real_1d_array &c, const real_1d_array &x, double &func, void *ptr)
{
// this callback calculates f(c,x)=exp(-c0*sqr(x0))
// where x is a position on X-axis and c is adjustable parameter
func = exp(-c[0]*pow(x[0],2));
}
int main(int argc, char **argv)
{
try
{
//
// In this example we demonstrate exponential fitting by
//
// f(x) = exp(-c*x^2)
//
// subject to box constraints
//
// 0.0 <= c <= 1.0
//
// using function value only. An unconstrained solution is c=1.5, but because of
// constraints we should get c=1.0 (at the boundary).
//
// IMPORTANT: the LSFIT optimizer supports parallel model evaluation and
// parallel numerical differentiation ('callback parallelism').
// This feature, which is present in commercial ALGLIB editions
// greatly accelerates fits with large datasets and/or
// expensive target functions.
//
// Callback parallelism is usually beneficial when a single
// pass over the entire dataset requires more than several
// milliseconds. This particular example, of course, is not
// suited for callback parallelism.
//
// See ALGLIB Reference Manual, 'Working with commercial version'
// section, and comments on lsfitfit() function for more
// information.
//
real_2d_array x = "[[-1],[-0.8],[-0.6],[-0.4],[-0.2],[0],[0.2],[0.4],[0.6],[0.8],[1.0]]";
real_1d_array y = "[0.223130, 0.382893, 0.582748, 0.786628, 0.941765, 1.000000, 0.941765, 0.786628, 0.582748, 0.382893, 0.223130]";
real_1d_array c = "[0.3]";
real_1d_array bndl = "[0.0]";
real_1d_array bndu = "[1.0]";
double epsx = 0.000001;
ae_int_t maxits = 0;
lsfitstate state;
lsfitreport rep;
double diffstep = 0.0001;
lsfitcreatef(x, y, c, diffstep, state);
lsfitsetbc(state, bndl, bndu);
lsfitsetcond(state, epsx, maxits);
alglib::lsfitfit(state, function_cx_1_func);
lsfitresults(state, c, rep);
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [1.0]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
void function_cx_1_func(const real_1d_array &c, const real_1d_array &x, double &func, void *ptr)
{
// this callback calculates f(c,x)=exp(-c0*sqr(x0))
// where x is a position on X-axis and c is adjustable parameter
func = exp(-c[0]*pow(x[0],2));
}
void function_cx_1_grad(const real_1d_array &c, const real_1d_array &x, double &func, real_1d_array &grad, void *ptr)
{
// this callback calculates f(c,x)=exp(-c0*sqr(x0)) and gradient G={df/dc[i]}
// where x is a position on X-axis and c is adjustable parameter.
// IMPORTANT: gradient is calculated with respect to C, not to X
func = exp(-c[0]*pow(x[0],2));
grad[0] = -pow(x[0],2)*func;
}
int main(int argc, char **argv)
{
try
{
//
// In this example we demonstrate exponential fitting by
//
// f(x) = exp(-c*x^2)
//
// using function value and gradient (with respect to c).
//
// IMPORTANT: the LSFIT optimizer supports parallel model evaluation and
// parallel numerical differentiation ('callback parallelism').
// This feature, which is present in commercial ALGLIB editions
// greatly accelerates fits with large datasets and/or
// expensive target functions.
//
// Callback parallelism is usually beneficial when a single
// pass over the entire dataset requires more than several
// milliseconds. This particular example, of course, is not
// suited for callback parallelism.
//
// See ALGLIB Reference Manual, 'Working with commercial version'
// section, and comments on lsfitfit() function for more
// information.
//
real_2d_array x = "[[-1],[-0.8],[-0.6],[-0.4],[-0.2],[0],[0.2],[0.4],[0.6],[0.8],[1.0]]";
real_1d_array y = "[0.223130, 0.382893, 0.582748, 0.786628, 0.941765, 1.000000, 0.941765, 0.786628, 0.582748, 0.382893, 0.223130]";
real_1d_array c = "[0.3]";
double epsx = 0.000001;
ae_int_t maxits = 0;
lsfitstate state;
lsfitreport rep;
//
// Fitting without weights
//
lsfitcreatefg(x, y, c, state);
lsfitsetcond(state, epsx, maxits);
alglib::lsfitfit(state, function_cx_1_func, function_cx_1_grad);
lsfitresults(state, c, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 2
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [1.5]
//
// Fitting with weights
// (you can change weights and see how it changes result)
//
real_1d_array w = "[1,1,1,1,1,1,1,1,1,1,1]";
lsfitcreatewfg(x, y, w, c, state);
lsfitsetcond(state, epsx, maxits);
alglib::lsfitfit(state, function_cx_1_func, function_cx_1_grad);
lsfitresults(state, c, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 2
printf("%s\n", c.tostring(1).c_str()); // EXPECTED: [1.5]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
void function_debt_func(const real_1d_array &c, const real_1d_array &x, double &func, void *ptr)
{
//
// this callback calculates f(c,x)=c[0]*(1+c[1]*(pow(x[0]-1999,c[2])-1))
//
func = c[0]*(1+c[1]*(pow(x[0]-1999,c[2])-1));
}
int main(int argc, char **argv)
{
try
{
//
// In this example we demonstrate fitting by
//
// f(x) = c[0]*(1+c[1]*((x-1999)^c[2]-1))
//
// subject to box constraints
//
// -INF < c[0] < +INF
// -10 <= c[1] <= +10
// 0.1 <= c[2] <= 2.0
//
// The data we want to fit are time series of Japan national debt
// collected from 2000 to 2008 measured in USD (dollars, not
// millions of dollars).
//
// Our variables are:
// c[0] - debt value at initial moment (2000),
// c[1] - direction coefficient (growth or decrease),
// c[2] - curvature coefficient.
// You may see that our variables are badly scaled - first one
// is order of 10^12, and next two are somewhere about 1 in
// magnitude. Such problem is difficult to solve without some
// kind of scaling.
// That is exactly where lsfitsetscale() function can be used.
// We set scale of our variables to [1.0E12, 1, 1], which allows
// us to easily solve this problem.
//
// You can try commenting out lsfitsetscale() call - and you will
// see that algorithm will fail to converge.
//
// IMPORTANT: the LSFIT optimizer supports parallel model evaluation and
// parallel numerical differentiation ('callback parallelism').
// This feature, which is present in commercial ALGLIB editions
// greatly accelerates fits with large datasets and/or
// expensive target functions.
//
// Callback parallelism is usually beneficial when a single
// pass over the entire dataset requires more than several
// milliseconds. This particular example, of course, is not
// suited for callback parallelism.
//
// See ALGLIB Reference Manual, 'Working with commercial version'
// section, and comments on lsfitfit() function for more
// information.
//
real_2d_array x = "[[2000],[2001],[2002],[2003],[2004],[2005],[2006],[2007],[2008]]";
real_1d_array y = "[4323239600000.0, 4560913100000.0, 5564091500000.0, 6743189300000.0, 7284064600000.0, 7050129600000.0, 7092221500000.0, 8483907600000.0, 8625804400000.0]";
real_1d_array c = "[1.0e+13, 1, 1]";
double epsx = 1.0e-5;
real_1d_array bndl = "[-inf, -10, 0.1]";
real_1d_array bndu = "[+inf, +10, 2.0]";
real_1d_array s = "[1.0e+12, 1, 1]";
ae_int_t maxits = 0;
lsfitstate state;
lsfitreport rep;
double diffstep = 1.0e-5;
lsfitcreatef(x, y, c, diffstep, state);
lsfitsetcond(state, epsx, maxits);
lsfitsetbc(state, bndl, bndu);
lsfitsetscale(state, s);
alglib::lsfitfit(state, function_debt_func);
lsfitresults(state, c, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 2
printf("%s\n", c.tostring(-2).c_str()); // EXPECTED: [4.142560E+12, 0.434240, 0.565376]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates polynomial fitting.
//
// Fitting is done by two (M=2) functions from polynomial basis:
// f0 = 1
// f1 = x
// Basically, it just a linear fit; more complex polynomials may be used
// (e.g. parabolas with M=3, cubic with M=4), but even such simple fit allows
// us to demonstrate polynomialfit() function in action.
//
// We have:
// * x set of abscissas
// * y experimental data
//
// Additionally we demonstrate weighted fitting, where second point has
// more weight than other ones.
//
real_1d_array x = "[0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]";
real_1d_array y = "[0.00,0.05,0.26,0.32,0.33,0.43,0.60,0.60,0.77,0.98,1.02]";
ae_int_t m = 2;
double t = 2;
barycentricinterpolant p;
polynomialfitreport rep;
double v;
//
// Fitting without individual weights
//
// NOTE: result is returned as barycentricinterpolant structure.
// if you want to get representation in the power basis,
// you can use barycentricbar2pow() function to convert
// from barycentric to power representation (see docs for
// POLINT subpackage for more info).
//
polynomialfit(x, y, m, p, rep);
v = barycentriccalc(p, t);
printf("%.2f\n", double(v)); // EXPECTED: 2.011
//
// Fitting with individual weights
//
// NOTE: slightly different result is returned
//
real_1d_array w = "[1,1.414213562,1,1,1,1,1,1,1,1,1]";
real_1d_array xc = "[]";
real_1d_array yc = "[]";
integer_1d_array dc = "[]";
polynomialfitwc(x, y, w, xc, yc, dc, m, p, rep);
v = barycentriccalc(p, t);
printf("%.2f\n", double(v)); // EXPECTED: 2.023
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates polynomial fitting.
//
// Fitting is done by two (M=2) functions from polynomial basis:
// f0 = 1
// f1 = x
// with simple constraint on function value
// f(0) = 0
// Basically, it just a linear fit; more complex polynomials may be used
// (e.g. parabolas with M=3, cubic with M=4), but even such simple fit allows
// us to demonstrate polynomialfit() function in action.
//
// We have:
// * x set of abscissas
// * y experimental data
// * xc points where constraints are placed
// * yc constraints on derivatives
// * dc derivative indices
// (0 means function itself, 1 means first derivative)
//
real_1d_array x = "[1.0,1.0]";
real_1d_array y = "[0.9,1.1]";
real_1d_array w = "[1,1]";
real_1d_array xc = "[0]";
real_1d_array yc = "[0]";
integer_1d_array dc = "[0]";
double t = 2;
ae_int_t m = 2;
barycentricinterpolant p;
polynomialfitreport rep;
double v;
polynomialfitwc(x, y, w, xc, yc, dc, m, p, rep);
v = barycentriccalc(p, t);
printf("%.2f\n", double(v)); // EXPECTED: 2.000
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// In this example we demonstrate penalized spline fitting of noisy data
//
// We have:
// * x - abscissas
// * y - vector of experimental data, straight line with small noise
//
real_1d_array x = "[0.00,0.10,0.20,0.30,0.40,0.50,0.60,0.70,0.80,0.90]";
real_1d_array y = "[0.10,0.00,0.30,0.40,0.30,0.40,0.62,0.68,0.75,0.95]";
double v;
spline1dinterpolant s;
spline1dfitreport rep;
//
// Fit with VERY small amount of smoothing (eps = 1.0E-9)
// and large number of basis functions (M=50).
//
// With such small regularization penalized spline almost fully reproduces function values
//
spline1dfit(x, y, 50, 0.000000001, s, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
v = spline1dcalc(s, 0.0);
printf("%.1f\n", double(v)); // EXPECTED: 0.10
//
// Fit with VERY large amount of smoothing eps=1000000
// and large number of basis functions (M=50).
//
// With such regularization our spline should become close to the straight line fit.
// We will compare its value in x=1.0 with results obtained from such fit.
//
spline1dfit(x, y, 50, 1000000, s, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
v = spline1dcalc(s, 1.0);
printf("%.2f\n", double(v)); // EXPECTED: 0.969
//
// In real life applications you may need some moderate degree of fitting,
// so we try to fit once more with eps=0.1.
//
spline1dfit(x, y, 50, 0.1, s, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
real_1d_array x = "[1,2,3,4,5,6,7,8]";
real_1d_array y = "[0.06313223,0.44552624,0.61838364,0.71385108,0.77345838,0.81383140,0.84280033,0.86449822]";
ae_int_t n = 8;
double a;
double b;
double c;
double d;
lsfitreport rep;
//
// Test logisticfit4() on carefully designed data with a priori known answer.
//
logisticfit4(x, y, n, a, b, c, d, rep);
printf("%.1f\n", double(a)); // EXPECTED: -1.000
printf("%.1f\n", double(b)); // EXPECTED: 1.200
printf("%.1f\n", double(c)); // EXPECTED: 0.900
printf("%.1f\n", double(d)); // EXPECTED: 1.000
//
// Evaluate model at point x=0.5
//
double v;
v = logisticcalc4(0.5, a, b, c, d);
printf("%.2f\n", double(v)); // EXPECTED: -0.33874308
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
real_1d_array x = "[1,2,3,4,5,6,7,8]";
real_1d_array y = "[0.1949776139,0.5710060208,0.726002637,0.8060434158,0.8534547965,0.8842071579,0.9054773317,0.9209088299]";
ae_int_t n = 8;
double a;
double b;
double c;
double d;
double g;
lsfitreport rep;
//
// Test logisticfit5() on carefully designed data with a priori known answer.
//
logisticfit5(x, y, n, a, b, c, d, g, rep);
printf("%.1f\n", double(a)); // EXPECTED: -1.000
printf("%.1f\n", double(b)); // EXPECTED: 1.200
printf("%.1f\n", double(c)); // EXPECTED: 0.900
printf("%.1f\n", double(d)); // EXPECTED: 1.000
printf("%.1f\n", double(g)); // EXPECTED: 1.200
//
// Evaluate model at point x=0.5
//
double v;
v = logisticcalc5(0.5, a, b, c, d, g);
printf("%.2f\n", double(v)); // EXPECTED: -0.2354656824
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
mannwhitneyu subpackagemannwhitneyutest function/************************************************************************* Mann-Whitney U-test This test checks hypotheses about whether X and Y are samples of two continuous distributions of the same shape and same median or whether their medians are different. The following tests are performed: * two-tailed test (null hypothesis - the medians are equal) * left-tailed test (null hypothesis - the median of the first sample is greater than or equal to the median of the second sample) * right-tailed test (null hypothesis - the median of the first sample is less than or equal to the median of the second sample). Requirements: * the samples are independent * X and Y are continuous distributions (or discrete distributions well- approximating continuous distributions) * distributions of X and Y have the same shape. The only possible difference is their position (i.e. the value of the median) * the number of elements in each sample is not less than 5 * the scale of measurement should be ordinal, interval or ratio (i.e. the test could not be applied to nominal variables). The test is non-parametric and doesn't require distributions to be normal. Input parameters: X - sample 1. Array whose index goes from 0 to N-1. N - size of the sample. N>=5 Y - sample 2. Array whose index goes from 0 to M-1. M - size of the sample. M>=5 Output parameters: BothTails - p-value for two-tailed test. If BothTails is less than the given significance level the null hypothesis is rejected. LeftTail - p-value for left-tailed test. If LeftTail is less than the given significance level, the null hypothesis is rejected. RightTail - p-value for right-tailed test. If RightTail is less than the given significance level the null hypothesis is rejected. To calculate p-values, special approximation is used. This method lets us calculate p-values with satisfactory accuracy in interval [0.0001, 1]. There is no approximation outside the [0.0001, 1] interval. Therefore, if the significance level outlies this interval, the test returns 0.0001. Relative precision of approximation of p-value: N M Max.err. Rms.err. 5..10 N..10 1.4e-02 6.0e-04 5..10 N..100 2.2e-02 5.3e-06 10..15 N..15 1.0e-02 3.2e-04 10..15 N..100 1.0e-02 2.2e-05 15..100 N..100 6.1e-03 2.7e-06 For N,M>100 accuracy checks weren't put into practice, but taking into account characteristics of asymptotic approximation used, precision should not be sharply different from the values for interval [5, 100]. NOTE: P-value approximation was optimized for 0.0001<=p<=0.2500. Thus, P's outside of this interval are enforced to these bounds. Say, you may quite often get P equal to exactly 0.25 or 0.0001. -- ALGLIB -- Copyright 09.04.2007 by Bochkanov Sergey *************************************************************************/void mannwhitneyutest(const real_1d_array &x, const ae_int_t n, const real_1d_array &y, const ae_int_t m, double &bothtails, double &lefttail, double &righttail, const xparams _xparams = alglib::xdefault);
matdet subpackage| matdet_d_1 | Determinant calculation, real matrix, short form | |
| matdet_d_2 | Determinant calculation, real matrix, full form | |
| matdet_d_3 | Determinant calculation, complex matrix, short form | |
| matdet_d_4 | Determinant calculation, complex matrix, full form | |
| matdet_d_5 | Determinant calculation, complex matrix with zero imaginary part, short form |
cmatrixdet function/************************************************************************* Calculation of the determinant of a general matrix Input parameters: A - matrix, array[0..N-1, 0..N-1] N - (optional) size of matrix A: * if given, only principal NxN submatrix is processed and overwritten. other elements are unchanged. * if not given, automatically determined from matrix size (A must be square matrix) Result: determinant of matrix A. -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/alglib::complex cmatrixdet(const complex_2d_array &a, const ae_int_t n, const xparams _xparams = alglib::xdefault); alglib::complex cmatrixdet(const complex_2d_array &a, const xparams _xparams = alglib::xdefault);
cmatrixludet function/************************************************************************* Determinant calculation of the matrix given by its LU decomposition. Input parameters: A - LU decomposition of the matrix (output of RMatrixLU subroutine). Pivots - table of permutations which were made during the LU decomposition. Output of RMatrixLU subroutine. N - (optional) size of matrix A: * if given, only principal NxN submatrix is processed and overwritten. other elements are unchanged. * if not given, automatically determined from matrix size (A must be square matrix) Result: matrix determinant. -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/alglib::complex cmatrixludet(const complex_2d_array &a, const integer_1d_array &pivots, const ae_int_t n, const xparams _xparams = alglib::xdefault); alglib::complex cmatrixludet(const complex_2d_array &a, const integer_1d_array &pivots, const xparams _xparams = alglib::xdefault);
rmatrixdet function/************************************************************************* Calculation of the determinant of a general matrix Input parameters: A - matrix, array[0..N-1, 0..N-1] N - (optional) size of matrix A: * if given, only principal NxN submatrix is processed and overwritten. other elements are unchanged. * if not given, automatically determined from matrix size (A must be square matrix) Result: determinant of matrix A. -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/double rmatrixdet(const real_2d_array &a, const ae_int_t n, const xparams _xparams = alglib::xdefault); double rmatrixdet(const real_2d_array &a, const xparams _xparams = alglib::xdefault);
rmatrixludet function/************************************************************************* Determinant calculation of the matrix given by its LU decomposition. Input parameters: A - LU decomposition of the matrix (output of RMatrixLU subroutine). Pivots - table of permutations which were made during the LU decomposition. Output of RMatrixLU subroutine. N - (optional) size of matrix A: * if given, only principal NxN submatrix is processed and overwritten. other elements are unchanged. * if not given, automatically determined from matrix size (A must be square matrix) Result: matrix determinant. -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/double rmatrixludet(const real_2d_array &a, const integer_1d_array &pivots, const ae_int_t n, const xparams _xparams = alglib::xdefault); double rmatrixludet(const real_2d_array &a, const integer_1d_array &pivots, const xparams _xparams = alglib::xdefault);
spdmatrixcholeskydet function/************************************************************************* Determinant calculation of the matrix given by the Cholesky decomposition. Input parameters: A - Cholesky decomposition, output of SMatrixCholesky subroutine. N - (optional) size of matrix A: * if given, only principal NxN submatrix is processed and overwritten. other elements are unchanged. * if not given, automatically determined from matrix size (A must be square matrix) As the determinant is equal to the product of squares of diagonal elements, it's not necessary to specify which triangle - lower or upper - the matrix is stored in. Result: matrix determinant. -- ALGLIB -- Copyright 2005-2008 by Bochkanov Sergey *************************************************************************/double spdmatrixcholeskydet(const real_2d_array &a, const ae_int_t n, const xparams _xparams = alglib::xdefault); double spdmatrixcholeskydet(const real_2d_array &a, const xparams _xparams = alglib::xdefault);
spdmatrixdet function/************************************************************************* Determinant calculation of the symmetric positive definite matrix. Input parameters: A - matrix, array[N,N] N - (optional) size of matrix A: * if given, only principal NxN submatrix is processed and overwritten. other elements are unchanged. * if not given, automatically determined from matrix size (A must be square matrix) IsUpper - storage type: * if True, symmetric matrix A is given by its upper triangle, and the lower triangle isn't used/changed by function * if False, symmetric matrix A is given by its lower triangle, and the upper triangle isn't used/changed by function Result: determinant of matrix A. If matrix A is not positive definite, an exception is generated. -- ALGLIB -- Copyright 2005-2008 by Bochkanov Sergey *************************************************************************/double spdmatrixdet(const real_2d_array &a, const ae_int_t n, const bool isupper, const xparams _xparams = alglib::xdefault); double spdmatrixdet(const real_2d_array &a, const bool isupper, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
real_2d_array b = "[[1,2],[2,1]]";
double a;
a = rmatrixdet(b);
printf("%.3f\n", double(a)); // EXPECTED: -3
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
real_2d_array b = "[[5,4],[4,5]]";
double a;
a = rmatrixdet(b, 2);
printf("%.3f\n", double(a)); // EXPECTED: 9
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
complex_2d_array b = "[[1+1i,2],[2,1-1i]]";
alglib::complex a;
a = cmatrixdet(b);
printf("%s\n", a.tostring(3).c_str()); // EXPECTED: -2
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
alglib::complex a;
complex_2d_array b = "[[5i,4],[4i,5]]";
a = cmatrixdet(b, 2);
printf("%s\n", a.tostring(3).c_str()); // EXPECTED: 9i
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
alglib::complex a;
complex_2d_array b = "[[9,1],[2,1]]";
a = cmatrixdet(b);
printf("%s\n", a.tostring(3).c_str()); // EXPECTED: 7
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
matgen subpackagecmatrixrndcond function/************************************************************************* Generation of random NxN complex matrix with given condition number C and norm2(A)=1 INPUT PARAMETERS: N - matrix size C - condition number (in 2-norm) OUTPUT PARAMETERS: A - random matrix with norm2(A)=1 and cond(A)=C -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void cmatrixrndcond(const ae_int_t n, const double c, complex_2d_array &a, const xparams _xparams = alglib::xdefault);
cmatrixrndorthogonal function/************************************************************************* Generation of a random Haar distributed orthogonal complex matrix INPUT PARAMETERS: N - matrix size, N>=1 OUTPUT PARAMETERS: A - orthogonal NxN matrix, array[0..N-1,0..N-1] NOTE: this function uses algorithm described in Stewart, G. W. (1980), "The Efficient Generation of Random Orthogonal Matrices with an Application to Condition Estimators". Speaking short, to generate an (N+1)x(N+1) orthogonal matrix, it: * takes an NxN one * takes uniformly distributed unit vector of dimension N+1. * constructs a Householder reflection from the vector, then applies it to the smaller matrix (embedded in the larger size with a 1 at the bottom right corner). -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void cmatrixrndorthogonal(const ae_int_t n, complex_2d_array &a, const xparams _xparams = alglib::xdefault);
cmatrixrndorthogonalfromtheleft function/************************************************************************* Multiplication of MxN complex matrix by MxM random Haar distributed complex orthogonal matrix INPUT PARAMETERS: A - matrix, array[0..M-1, 0..N-1] M, N- matrix size OUTPUT PARAMETERS: A - Q*A, where Q is random MxM orthogonal matrix -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void cmatrixrndorthogonalfromtheleft(complex_2d_array &a, const ae_int_t m, const ae_int_t n, const xparams _xparams = alglib::xdefault);
cmatrixrndorthogonalfromtheright function/************************************************************************* Multiplication of MxN complex matrix by NxN random Haar distributed complex orthogonal matrix INPUT PARAMETERS: A - matrix, array[0..M-1, 0..N-1] M, N- matrix size OUTPUT PARAMETERS: A - A*Q, where Q is random NxN orthogonal matrix -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void cmatrixrndorthogonalfromtheright(complex_2d_array &a, const ae_int_t m, const ae_int_t n, const xparams _xparams = alglib::xdefault);
hmatrixrndcond function/************************************************************************* Generation of random NxN Hermitian matrix with given condition number and norm2(A)=1 INPUT PARAMETERS: N - matrix size C - condition number (in 2-norm) OUTPUT PARAMETERS: A - random matrix with norm2(A)=1 and cond(A)=C -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void hmatrixrndcond(const ae_int_t n, const double c, complex_2d_array &a, const xparams _xparams = alglib::xdefault);
hmatrixrndmultiply function/************************************************************************* Hermitian multiplication of NxN matrix by random Haar distributed complex orthogonal matrix INPUT PARAMETERS: A - matrix, array[0..N-1, 0..N-1] N - matrix size OUTPUT PARAMETERS: A - Q^H*A*Q, where Q is random NxN orthogonal matrix -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void hmatrixrndmultiply(complex_2d_array &a, const ae_int_t n, const xparams _xparams = alglib::xdefault);
hpdmatrixrndcond function/************************************************************************* Generation of random NxN Hermitian positive definite matrix with given condition number and norm2(A)=1 INPUT PARAMETERS: N - matrix size C - condition number (in 2-norm) OUTPUT PARAMETERS: A - random HPD matrix with norm2(A)=1 and cond(A)=C -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void hpdmatrixrndcond(const ae_int_t n, const double c, complex_2d_array &a, const xparams _xparams = alglib::xdefault);
rmatrixrndcond function/************************************************************************* Generation of random NxN matrix with given condition number and norm2(A)=1 INPUT PARAMETERS: N - matrix size C - condition number (in 2-norm) OUTPUT PARAMETERS: A - random matrix with norm2(A)=1 and cond(A)=C -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void rmatrixrndcond(const ae_int_t n, const double c, real_2d_array &a, const xparams _xparams = alglib::xdefault);
rmatrixrndorthogonal function/************************************************************************* Generation of a random uniformly distributed (Haar) orthogonal matrix INPUT PARAMETERS: N - matrix size, N>=1 OUTPUT PARAMETERS: A - orthogonal NxN matrix, array[0..N-1,0..N-1] NOTE: this function uses algorithm described in Stewart, G. W. (1980), "The Efficient Generation of Random Orthogonal Matrices with an Application to Condition Estimators". Speaking short, to generate an (N+1)x(N+1) orthogonal matrix, it: * takes an NxN one * takes uniformly distributed unit vector of dimension N+1. * constructs a Householder reflection from the vector, then applies it to the smaller matrix (embedded in the larger size with a 1 at the bottom right corner). -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void rmatrixrndorthogonal(const ae_int_t n, real_2d_array &a, const xparams _xparams = alglib::xdefault);
rmatrixrndorthogonalfromtheleft function/************************************************************************* Multiplication of MxN matrix by MxM random Haar distributed orthogonal matrix INPUT PARAMETERS: A - matrix, array[0..M-1, 0..N-1] M, N- matrix size OUTPUT PARAMETERS: A - Q*A, where Q is random MxM orthogonal matrix -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void rmatrixrndorthogonalfromtheleft(real_2d_array &a, const ae_int_t m, const ae_int_t n, const xparams _xparams = alglib::xdefault);
rmatrixrndorthogonalfromtheright function/************************************************************************* Multiplication of MxN matrix by NxN random Haar distributed orthogonal matrix INPUT PARAMETERS: A - matrix, array[0..M-1, 0..N-1] M, N- matrix size OUTPUT PARAMETERS: A - A*Q, where Q is random NxN orthogonal matrix -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void rmatrixrndorthogonalfromtheright(real_2d_array &a, const ae_int_t m, const ae_int_t n, const xparams _xparams = alglib::xdefault);
smatrixrndcond function/************************************************************************* Generation of random NxN symmetric matrix with given condition number and norm2(A)=1 INPUT PARAMETERS: N - matrix size C - condition number (in 2-norm) OUTPUT PARAMETERS: A - random matrix with norm2(A)=1 and cond(A)=C -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void smatrixrndcond(const ae_int_t n, const double c, real_2d_array &a, const xparams _xparams = alglib::xdefault);
smatrixrndmultiply function/************************************************************************* Symmetric multiplication of NxN matrix by random Haar distributed orthogonal matrix INPUT PARAMETERS: A - matrix, array[0..N-1, 0..N-1] N - matrix size OUTPUT PARAMETERS: A - Q'*A*Q, where Q is random NxN orthogonal matrix -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void smatrixrndmultiply(real_2d_array &a, const ae_int_t n, const xparams _xparams = alglib::xdefault);
spdmatrixrndcond function/************************************************************************* Generation of random NxN symmetric positive definite matrix with given condition number and norm2(A)=1 INPUT PARAMETERS: N - matrix size C - condition number (in 2-norm) OUTPUT PARAMETERS: A - random SPD matrix with norm2(A)=1 and cond(A)=C -- ALGLIB routine -- 04.12.2009 Bochkanov Sergey *************************************************************************/void spdmatrixrndcond(const ae_int_t n, const double c, real_2d_array &a, const xparams _xparams = alglib::xdefault);
matinv subpackage| matinv_d_c1 | Complex matrix inverse | |
| matinv_d_hpd1 | HPD matrix inverse | |
| matinv_d_r1 | Real matrix inverse | |
| matinv_d_spd1 | SPD matrix inverse |
matinvreport class/************************************************************************* Matrix inverse report: * terminationtype completion code: * 1 for success * -3 for failure due to the matrix being singular or nearly-singular * r1 reciprocal of condition number in 1-norm * rinf reciprocal of condition number in inf-norm *************************************************************************/class matinvreport { public: matinvreport(); matinvreport(const matinvreport &rhs); matinvreport& operator=(const matinvreport &rhs); virtual ~matinvreport(); ae_int_t terminationtype; double r1; double rinf; };
cmatrixinverse function/************************************************************************* Inversion of a general matrix. Input parameters: A - matrix N - size of the matrix A (optional): * if given, only principal NxN submatrix is processed and overwritten. Trailing elements are unchanged. * if not given, the size is automatically determined from the matrix size (A must be a square matrix) Output parameters: A - inverse of matrix A, array[N,N]: * for rep.terminationtype>0, contains matrix inverse * for rep.terminationtype<0, zero-filled Rep - solver report: * rep.terminationtype>0 for success, <0 for failure * see below for more info SOLVER REPORT Subroutine sets following fields of the Rep structure: * terminationtype completion code: * 1 for success * -3 for a singular or extremely ill-conditioned matrix * r1 reciprocal of condition number: 1/cond(A), 1-norm. * rinf reciprocal of condition number: 1/cond(A), inf-norm. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/void cmatrixinverse(complex_2d_array &a, const ae_int_t n, matinvreport &rep, const xparams _xparams = alglib::xdefault); void cmatrixinverse(complex_2d_array &a, matinvreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
cmatrixluinverse function/************************************************************************* Inversion of a matrix given by its LU decomposition. INPUT PARAMETERS: A - LU decomposition of the matrix (output of CMatrixLU subroutine). Pivots - table of permutations (the output of CMatrixLU subroutine). N - size of the matrix A (optional): * if given, only principal NxN submatrix is processed and overwritten. Trailing elements are unchanged. * if not given, the size is automatically determined from the matrix size (A must be a square matrix) OUTPUT PARAMETERS: A - inverse of matrix A, array[N,N]: * for rep.terminationtype>0, contains matrix inverse * for rep.terminationtype<0, zero-filled Rep - solver report: * rep.terminationtype>0 for success, <0 for failure * see below for more info SOLVER REPORT Subroutine sets following fields of the Rep structure: * terminationtype completion code: * 1 for success * -3 for a singular or extremely ill-conditioned matrix * r1 reciprocal of condition number: 1/cond(A), 1-norm. * rinf reciprocal of condition number: 1/cond(A), inf-norm. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 05.02.2010 Bochkanov Sergey *************************************************************************/void cmatrixluinverse(complex_2d_array &a, const integer_1d_array &pivots, const ae_int_t n, matinvreport &rep, const xparams _xparams = alglib::xdefault); void cmatrixluinverse(complex_2d_array &a, const integer_1d_array &pivots, matinvreport &rep, const xparams _xparams = alglib::xdefault);
cmatrixtrinverse function/************************************************************************* Triangular matrix inverse (complex) The subroutine inverts the following types of matrices: * upper triangular * upper triangular with unit diagonal * lower triangular * lower triangular with unit diagonal In case of an upper (lower) triangular matrix, the inverse matrix will also be upper (lower) triangular, and after the end of the algorithm, the inverse matrix replaces the source matrix. The elements below (above) the main diagonal are not changed by the algorithm. If the matrix has a unit diagonal, the inverse matrix also has a unit diagonal, and the diagonal elements are not passed to the algorithm. INPUT PARAMETERS: A - matrix, array[0..N-1, 0..N-1]. N - size of the matrix A (optional): * if given, only principal NxN submatrix is processed and overwritten. Trailing elements are unchanged. * if not given, the size is automatically determined from the matrix size (A must be a square matrix) IsUpper - True, if the matrix is upper triangular. IsUnit - diagonal type (optional): * if True, matrix has unit diagonal (a[i,i] are NOT used) * if False, matrix diagonal is arbitrary * if not given, False is assumed OUTPUT PARAMETERS: A - inverse of matrix A, array[N,N]: * for rep.terminationtype>0, contains matrix inverse * for rep.terminationtype<0, zero-filled Rep - solver report: * rep.terminationtype>0 for success, <0 for failure * see below for more info SOLVER REPORT Subroutine sets following fields of the Rep structure: * terminationtype completion code: * 1 for success * -3 for a singular or extremely ill-conditioned matrix * r1 reciprocal of condition number: 1/cond(A), 1-norm. * rinf reciprocal of condition number: 1/cond(A), inf-norm. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 05.02.2010 by Bochkanov Sergey *************************************************************************/void cmatrixtrinverse(complex_2d_array &a, const ae_int_t n, const bool isupper, const bool isunit, matinvreport &rep, const xparams _xparams = alglib::xdefault); void cmatrixtrinverse(complex_2d_array &a, const bool isupper, matinvreport &rep, const xparams _xparams = alglib::xdefault);
hpdmatrixcholeskyinverse function/************************************************************************* Inversion of a Hermitian positive definite matrix which is given by Cholesky decomposition. Input parameters: A - Cholesky decomposition of the matrix to be inverted: A=U'*U or A = L*L'. Output of HPDMatrixCholesky subroutine. N - size of the matrix A (optional): * if given, only principal NxN submatrix is processed and overwritten. Trailing elements are unchanged. * if not given, the size is automatically determined from the matrix size (A must be a square matrix) IsUpper - storage type: * if True, symmetric matrix A is given by its upper triangle, and the lower triangle isn't used/changed by function * if False, symmetric matrix A is given by its lower triangle, and the upper triangle isn't used/changed by function OUTPUT PARAMETERS: A - inverse of matrix A, array[N,N]: * for rep.terminationtype>0, contains matrix inverse * for rep.terminationtype<0, zero-filled Rep - solver report: * rep.terminationtype>0 for success, <0 for failure * see below for more info SOLVER REPORT Subroutine sets following fields of the Rep structure: * terminationtype completion code: * 1 for success * -3 for a singular or extremely ill-conditioned matrix * r1 reciprocal of condition number: 1/cond(A), 1-norm. * rinf reciprocal of condition number: 1/cond(A), inf-norm. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 10.02.2010 Bochkanov Sergey *************************************************************************/void hpdmatrixcholeskyinverse(complex_2d_array &a, const ae_int_t n, const bool isupper, matinvreport &rep, const xparams _xparams = alglib::xdefault); void hpdmatrixcholeskyinverse(complex_2d_array &a, const bool isupper, matinvreport &rep, const xparams _xparams = alglib::xdefault);
hpdmatrixinverse function/************************************************************************* Inversion of a Hermitian positive definite matrix. Given an upper or lower triangle of a Hermitian positive definite matrix, the algorithm generates matrix A^-1 and saves the upper or lower triangle depending on the input. INPUT PARAMETERS: A - matrix to be inverted (upper or lower triangle), array[N,N] N - size of the matrix A (optional): * if given, only principal NxN submatrix is processed and overwritten. Trailing elements are unchanged. * if not given, the size is automatically determined from the matrix size (A must be a square matrix) IsUpper - storage type: * if True, symmetric matrix A is given by its upper triangle, and the lower triangle isn't used/changed by function * if False, symmetric matrix A is given by its lower triangle, and the upper triangle isn't used/changed by function OUTPUT PARAMETERS: A - inverse of matrix A, array[N,N]: * for rep.terminationtype>0, contains matrix inverse * for rep.terminationtype<0, zero-filled Rep - solver report: * rep.terminationtype>0 for success, <0 for failure * see below for more info SOLVER REPORT Subroutine sets following fields of the Rep structure: * terminationtype completion code: * 1 for success * -3 for a singular or extremely ill-conditioned matrix * r1 reciprocal of condition number: 1/cond(A), 1-norm. * rinf reciprocal of condition number: 1/cond(A), inf-norm. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 10.02.2010 Bochkanov Sergey *************************************************************************/void hpdmatrixinverse(complex_2d_array &a, const ae_int_t n, const bool isupper, matinvreport &rep, const xparams _xparams = alglib::xdefault); void hpdmatrixinverse(complex_2d_array &a, const bool isupper, matinvreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixinverse function/************************************************************************* Inversion of a general matrix. INPUT PARAMETERS: A - matrix. N - size of the matrix A (optional): * if given, only principal NxN submatrix is processed and overwritten. Trailing elements are unchanged. * if not given, the size is automatically determined from the matrix size (A must be a square matrix) OUTPUT PARAMETERS: A - inverse of matrix A, array[N,N]: * for rep.terminationtype>0, contains matrix inverse * for rep.terminationtype<0, zero-filled Rep - solver report: * rep.terminationtype>0 for success, <0 for failure * see below for more info SOLVER REPORT Subroutine sets following fields of the Rep structure: * terminationtype completion code: * 1 for success * -3 for a singular or extremely ill-conditioned matrix * r1 reciprocal of condition number: 1/cond(A), 1-norm. * rinf reciprocal of condition number: 1/cond(A), inf-norm. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 2005-2010 by Bochkanov Sergey *************************************************************************/void rmatrixinverse(real_2d_array &a, const ae_int_t n, matinvreport &rep, const xparams _xparams = alglib::xdefault); void rmatrixinverse(real_2d_array &a, matinvreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
rmatrixluinverse function/************************************************************************* Inversion of a matrix given by its LU decomposition. INPUT PARAMETERS: A - LU decomposition of the matrix (output of RMatrixLU subroutine). Pivots - table of permutations (the output of RMatrixLU subroutine). N - size of the matrix A (optional): * if given, only principal NxN submatrix is processed and overwritten. Trailing elements are unchanged. * if not given, the size is automatically determined from the matrix size (A must be a square matrix) OUTPUT PARAMETERS: A - inverse of matrix A, array[N,N]: * for rep.terminationtype>0, contains matrix inverse * for rep.terminationtype<0, zero-filled Rep - solver report: * rep.terminationtype>0 for success, <0 for failure * see below for more info SOLVER REPORT Subroutine sets following fields of the Rep structure: * terminationtype completion code: * 1 for success * -3 for a singular or extremely ill-conditioned matrix * r1 reciprocal of condition number: 1/cond(A), 1-norm. * rinf reciprocal of condition number: 1/cond(A), inf-norm. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 05.02.2010 Bochkanov Sergey *************************************************************************/void rmatrixluinverse(real_2d_array &a, const integer_1d_array &pivots, const ae_int_t n, matinvreport &rep, const xparams _xparams = alglib::xdefault); void rmatrixluinverse(real_2d_array &a, const integer_1d_array &pivots, matinvreport &rep, const xparams _xparams = alglib::xdefault);
rmatrixtrinverse function/************************************************************************* Triangular matrix inverse (real) The subroutine inverts the following types of matrices: * upper triangular * upper triangular with unit diagonal * lower triangular * lower triangular with unit diagonal In case of an upper (lower) triangular matrix, the inverse matrix will also be upper (lower) triangular, and after the end of the algorithm, the inverse matrix replaces the source matrix. The elements below (above) the main diagonal are not changed by the algorithm. If the matrix has a unit diagonal, the inverse matrix also has a unit diagonal, and the diagonal elements are not passed to the algorithm. INPUT PARAMETERS: A - matrix, array[0..N-1, 0..N-1]. N - size of the matrix A (optional): * if given, only principal NxN submatrix is processed and overwritten. Trailing elements are unchanged. * if not given, the size is automatically determined from the matrix size (A must be a square matrix) IsUpper - True, if the matrix is upper triangular. IsUnit - diagonal type (optional): * if True, matrix has unit diagonal (a[i,i] are NOT used) * if False, matrix diagonal is arbitrary * if not given, False is assumed OUTPUT PARAMETERS: A - inverse of matrix A, array[N,N]: * for rep.terminationtype>0, contains matrix inverse * for rep.terminationtype<0, zero-filled Rep - solver report: * rep.terminationtype>0 for success, <0 for failure * see below for more info SOLVER REPORT Subroutine sets following fields of the Rep structure: * terminationtype completion code: * 1 for success * -3 for a singular or extremely ill-conditioned matrix * r1 reciprocal of condition number: 1/cond(A), 1-norm. * rinf reciprocal of condition number: 1/cond(A), inf-norm. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB -- Copyright 05.02.2010 by Bochkanov Sergey *************************************************************************/void rmatrixtrinverse(real_2d_array &a, const ae_int_t n, const bool isupper, const bool isunit, matinvreport &rep, const xparams _xparams = alglib::xdefault); void rmatrixtrinverse(real_2d_array &a, const bool isupper, matinvreport &rep, const xparams _xparams = alglib::xdefault);
spdmatrixcholeskyinverse function/************************************************************************* Inversion of a symmetric positive definite matrix which is given by Cholesky decomposition. INPUT PARAMETERS: A - Cholesky decomposition of the matrix to be inverted: A=U'*U or A = L*L'. Output of SPDMatrixCholesky subroutine. N - size of the matrix A (optional): * if given, only principal NxN submatrix is processed and overwritten. Trailing elements are unchanged. * if not given, the size is automatically determined from the matrix size (A must be a square matrix) IsUpper - storage type: * if True, the symmetric matrix A is given by its upper triangle, and the lower triangle isn't used/changed by the function * if False, the symmetric matrix A is given by its lower triangle, and the upper triangle isn't used/changed by the function OUTPUT PARAMETERS: A - inverse of matrix A, array[N,N]: * for rep.terminationtype>0, corresponding triangle contains inverse matrix, the other triangle is not modified. * for rep.terminationtype<0, corresponding triangle is zero-filled; the other triangle is not modified. Rep - solver report: * rep.terminationtype>0 for success, <0 for failure * see below for more info SOLVER REPORT Subroutine sets following fields of the Rep structure: * terminationtype completion code: * 1 for success * -3 for a singular or extremely ill-conditioned matrix * r1 reciprocal of condition number: 1/cond(A), 1-norm. * rinf reciprocal of condition number: 1/cond(A), inf-norm. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 10.02.2010 Bochkanov Sergey *************************************************************************/void spdmatrixcholeskyinverse(real_2d_array &a, const ae_int_t n, const bool isupper, matinvreport &rep, const xparams _xparams = alglib::xdefault); void spdmatrixcholeskyinverse(real_2d_array &a, const bool isupper, matinvreport &rep, const xparams _xparams = alglib::xdefault);
spdmatrixinverse function/************************************************************************* Inversion of a symmetric positive definite matrix. Given an upper or lower triangle of a symmetric positive definite matrix, the algorithm generates matrix A^-1 and saves the upper or lower triangle depending on the input. INPUT PARAMETERS: A - matrix to be inverted (upper or lower triangle), array[N,N] N - size of the matrix A (optional): * if given, only principal NxN submatrix is processed and overwritten. Trailing elements are unchanged. * if not given, the size is automatically determined from the matrix size (A must be a square matrix) IsUpper - storage type: * if True, symmetric matrix A is given by its upper triangle, and the lower triangle isn't used/changed by function * if False, symmetric matrix A is given by its lower triangle, and the upper triangle isn't used/changed by function OUTPUT PARAMETERS: A - inverse of matrix A, array[N,N]: * for rep.terminationtype>0, contains matrix inverse * for rep.terminationtype<0, zero-filled Rep - solver report: * rep.terminationtype>0 for success, <0 for failure * see below for more info SOLVER REPORT Subroutine sets following fields of the Rep structure: * terminationtype completion code: * 1 for success * -3 for a singular or extremely ill-conditioned matrix * r1 reciprocal of condition number: 1/cond(A), 1-norm. * rinf reciprocal of condition number: 1/cond(A), inf-norm. ! FREE EDITION OF ALGLIB: ! ! Free Edition of ALGLIB supports following important features for this ! function: ! * C++ version: x64 SIMD support using C++ intrinsics ! * C# version: x64 SIMD support using NET5/NetCore hardware intrinsics ! ! We recommend you to read 'Compiling ALGLIB' section of the ALGLIB ! Reference Manual in order to find out how to activate SIMD support ! in ALGLIB. ! COMMERCIAL EDITION OF ALGLIB: ! ! Commercial Edition of ALGLIB includes following important improvements ! of this function: ! * high-performance native backend with same C# interface (C# version) ! * multithreading support (C++ and C# versions) ! * hardware vendor (Intel, ARM) implementations of linear algebra and ! other primitives (C++ and C# versions) ! ! We recommend you to read 'Working with commercial version' section of ! ALGLIB Reference Manual in order to find out how to use performance- ! related features provided by commercial edition of ALGLIB. -- ALGLIB routine -- 10.02.2010 Bochkanov Sergey *************************************************************************/void spdmatrixinverse(real_2d_array &a, const ae_int_t n, const bool isupper, matinvreport &rep, const xparams _xparams = alglib::xdefault); void spdmatrixinverse(real_2d_array &a, const bool isupper, matinvreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
complex_2d_array a = "[[1i,-1],[1i,1]]";
matinvreport rep;
cmatrixinverse(a, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", a.tostring(4).c_str()); // EXPECTED: [[-0.5i,-0.5i],[-0.5,0.5]]
printf("%.4f\n", double(rep.r1)); // EXPECTED: 0.5
printf("%.4f\n", double(rep.rinf)); // EXPECTED: 0.5
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
complex_2d_array a = "[[2,1],[1,2]]";
matinvreport rep;
//
// The matrix is given by its upper and lower triangles
//
// [ 2 1 ]
// [ 1 2 ]
//
// However, hpdmatrixinverse() accepts and modifies only one triangle - either
// the upper or the lower one. The other triangle is left untouched. In this example
// we modify the lower triangle. Thus, the inverse matrix is
//
// [ 2/3 -1/3 ]
// [ -1/3 2/3 ]
//
// but only lower triangle is returned, and the upper triangle is not modified:
//
// [ 2/3 1 ]
// [ -1/3 2/3 ]
//
//
bool isupper = false;
hpdmatrixinverse(a, isupper, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", a.tostring(4).c_str()); // EXPECTED: [[0.666666,1],[-0.333333,0.666666]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
real_2d_array a = "[[1,-1],[1,1]]";
matinvreport rep;
rmatrixinverse(a, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", a.tostring(4).c_str()); // EXPECTED: [[0.5,0.5],[-0.5,0.5]]
printf("%.4f\n", double(rep.r1)); // EXPECTED: 0.5
printf("%.4f\n", double(rep.rinf)); // EXPECTED: 0.5
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "linalg.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
real_2d_array a = "[[2,1],[1,2]]";
matinvreport rep;
//
// The matrix is given by its upper and lower triangles
//
// [ 2 1 ]
// [ 1 2 ]
//
// However, spdmatrixinverse() accepts and modifies only one triangle - either
// the upper or the lower one. The other triangle is left untouched. In this example
// we modify the lower triangle. Thus, the inverse matrix is
//
// [ 2/3 -1/3 ]
// [ -1/3 2/3 ]
//
// but only lower triangle is returned, and the upper triangle is not modified:
//
// [ 2/3 1 ]
// [ -1/3 2/3 ]
//
//
bool isupper = false;
spdmatrixinverse(a, isupper, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 1
printf("%s\n", a.tostring(4).c_str()); // EXPECTED: [[0.666666,1],[-0.333333,0.666666]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
mcmc subpackage| mcmc_basic | Markov Chain Monte Carlo sampling of a 2D Gaussian |
mcmcreport class/************************************************************************* These fields store MCMC report: * nfev number of function evaluations * acceptrate acceptance rate of a MCMC algo; when parallel tempering is used, this field stores acceptance rate for the lowest level (T=1). * swapacceptrate acceptance rate for swaps between levels of the temperature ladder. When no parallel tempering is used, stores zero. * autocorrtimes array[N], per-variable autocorrelation times *************************************************************************/class mcmcreport { public: mcmcreport(); mcmcreport(const mcmcreport &rhs); mcmcreport& operator=(const mcmcreport &rhs); virtual ~mcmcreport(); ae_int_t nfev; double acceptrate; double swapacceptrate; real_1d_array autocorrtimes; };
mcmcstate class/************************************************************************* This object stores MCMC sampler. You should use functions provided by the MCMC subpackage to work with this object. *************************************************************************/class mcmcstate { public: mcmcstate(); mcmcstate(const mcmcstate &rhs); mcmcstate& operator=(const mcmcstate &rhs); virtual ~mcmcstate(); };
mcmccreate1 function/************************************************************************* This function initializes MCMC sampler using single initial point to seed the population. The population is generated around the initial point with random Gaussian noise being added, having per-variable magnitude equal to XStdDev or (if MCMCSetScale() was called) equal to XStdDev*S[I]. INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of X are used * if not given, automatically determined from size of X X - starting point used to seed a MCMC algo, array[N]: * it is better to have X not too far away from the maximum of log-likelihood * any point will do, if no maximum location is unknown XStdDev - standard deviation of a population generated around X: * strictly greater than zero * nearly zero values are likely to cause population to stagnate, whilst too large values are likely to cause population to spend excessive time converging OUTPUT PARAMETERS: State - structure stores MCMC sampler state -- ALGLIB -- Copyright 20.01.2025 by Bochkanov Sergey *************************************************************************/void mcmccreate1(const ae_int_t n, const real_1d_array &x, const double xstddev, mcmcstate &state, const xparams _xparams = alglib::xdefault); void mcmccreate1(const real_1d_array &x, const double xstddev, mcmcstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
mcmccreatefrompopulation function/************************************************************************* This function initializes MCMC sampler using a population of user-specified points. A specific sampling algorithm that needs an initial population will use user-provided points. If an algorithm needs more initial points than was specified, additional points will be randomly generated using population as a distribution reference. INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of P are used * if not given, automatically determined from size of P P - initial points, array[PopSize,N] PopSize - population size, PopSize>0: * if given, only leading PopSize elements of P are used * if not given, automatically determined from size of P OUTPUT PARAMETERS: State - structure stores MCMC sampler state -- ALGLIB -- Copyright 20.05.2025 by Bochkanov Sergey *************************************************************************/void mcmccreatefrompopulation(const ae_int_t n, const real_2d_array &p, const ae_int_t popsize, mcmcstate &state, const xparams _xparams = alglib::xdefault); void mcmccreatefrompopulation(const real_2d_array &p, mcmcstate &state, const xparams _xparams = alglib::xdefault);
mcmciteration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool mcmciteration(mcmcstate &state, const xparams _xparams = alglib::xdefault);
mcmcrequesttermination function/************************************************************************* This subroutine submits request for termination of a running MCMC sampler. It should be called from user-supplied callback when user decides that it is time to "smoothly" terminate optimization process. As a result, sampler stops at the point which was "current accepted" when termination request was submitted. Alternatively, this function can be called from some other thread (different from one where the sampler is running). INPUT PARAMETERS: State - sampler structure NOTE: after request for termination sampler may perform several additional calls to user-supplied callbacks. It does NOT guarantee to stop immediately - it just guarantees that these additional calls will be discarded later. NOTE: calling this function on sampler which is NOT running will have no effect. NOTE: multiple calls to this function are possible. First call is counted, subsequent calls are silently ignored. -- ALGLIB -- Copyright 25.02.2025 by Bochkanov Sergey *************************************************************************/void mcmcrequesttermination(mcmcstate &state, const xparams _xparams = alglib::xdefault);
mcmcrestart function/************************************************************************* This function tells the sampler to restart the next sampling session using the most recent population as an initial state. The new sampling session is still considered an independent one. It uses sampling distribution of the previous session to provide a smooth restart, but its results do not include samples collected during the previous session. It is possible to specify different sampling algorithm or change parameters of the algorithm. If population size has changed, then we have two options: * the new population size is less than the previous one; the population is truncated (only leading NewPopSize elements are retained) * the new population size is greater than the previous one; in this case, leading OldPopSize elements are retained from the previous population, and the rest (NewPopSize-OldPopSize) is randomly initialized using the previous population as a reference distribution. INPUT PARAMETERS: State - structure which stores sampler state RESULT: * False, if no previous population was stored in the sampler (the restart was requested prior to running anything, so we have nothing to restart from). In this case, the sampler will silently reuse previous initial population generation strategy. * True, if a request was successfully accepted. NOTE: this function also tells the sampler not to re-seed internal RNG, so the new session will produce the same sequence of sampling decisions. -- ALGLIB -- Copyright 15.05.2025 by Bochkanov Sergey *************************************************************************/bool mcmcrestart(mcmcstate &state, const xparams _xparams = alglib::xdefault);
mcmcresults function/************************************************************************* Extract MCMC sampler results from the sampler. This function has significant overhead coming from two sources: * overhead of copying PopSize*EpochsCnt*N-sized array from internal memory * overhead of computing per-variable integrated autocorrelating time INPUT PARAMETERS: State - MCMC sampler, either after return from mcmcrun() or still running (in the latter case, this function can be safely called only from the rep() callback). OUTPUT PARAMETERS: Sample - array[SampleSize,N+1], current sample: * first N columns store variable values, the last one stores log-likelihood value as computed by the callback * first PopSize rows store population snapshot after the iteration #0, subsequent PopSize rows correspond to iteration #1 and so on. * each snapshot (a set of PopSize rows) stores positions of PopSize walkers, each walker having the same position in each of SampleSize snapshots. Thus, walker #I at the iteration #J is stored at the row PopSize*J+I. SampleSize - current sample size: * for a sampler that stopped it is equal to PopSize*EpochsCnt * for a sampler that is still running, we have 0<=SampleSize<PopSize*EpochsCnt. Zero sample is reported upon the first call to rep(). Rep - other information being reported, including: * acceptance rate * per-variable integrated autocorrelation time IMPORTANT: unlike other [something]results() functions from ALGLIB library this function can be called on a sampler that is still running. Thus, it can be used to peek into a sampler from the rep() callback, e.g. to check convergence. When called prior to MCMC completion, it will return in Sample/SampleSize/Rep the most recent snapshot of MCMC sampling. Note that due to significant overhead (iteration with number #K involves copying O(K) data and doing between O(K) and O(K*logK) job) calling this function after each iteration will lead to a catastrophic slowdown of the sampler: its running time will become quadratic with respect to iterations count! Consider doing it after each 100-th iteration or something like that. IMPORTANT: THIS FUNCTION IS NOT THREAD-SAFE! Thus, the only place where it can be called is rep() callback, and it must complete prior to returning from the callback into the sampler. NOTE: burn-in iterations are not reported. Similarly, for a primary phase only each ThinFactor-th iteration is reported. -- ALGLIB -- Copyright 18.01.2025 by Bochkanov Sergey *************************************************************************/void mcmcresults(const mcmcstate &state, real_2d_array &sample, ae_int_t &samplesize, mcmcreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
mcmcresultsbuf function/************************************************************************* Buffered implementation of MCMCResults() which uses pre-allocated buffer to store X[]. If buffer size is too small, it resizes buffer. It is intended to be used in the inner cycles of performance critical algorithms where array reallocation penalty is too large to be ignored. -- ALGLIB -- Copyright 18.01.2025 by Bochkanov Sergey *************************************************************************/void mcmcresultsbuf(const mcmcstate &state, real_2d_array &sample, ae_int_t &samplesize, mcmcreport &rep, const xparams _xparams = alglib::xdefault);
mcmcrun function/************************************************************************* These functions accept following parameters: state - algorithm state func - callback which calculates function (or merit function) value func at given point x rep - optional callback which is called after each iteration can be NULL ptr - optional pointer which is passed to func/grad/hess/jac/rep can be NULL -- ALGLIB -- Copyright 20.01.2025 by Bochkanov Sergey *************************************************************************/void mcmcrun(mcmcstate &state, void (*func)(const real_1d_array &x, double &func, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault);
Examples: [1]
mcmcsetalgode function/************************************************************************* This function sets MCMC algorithm to Goodman-Weare ( ensemble MCMC) with the specified ensemble size and number of iterations being reported. Uses DE move, as defined in 'RUN DMC: an efficient, parallel code for analyzing radial velocity observations using n-body integrations and differential evolution Markov chain Monte Carlo' by Benjamin Nelson, Eric B. Ford, and Matthew J. Payne. NOTE: the sampler always reports PopSize*EpochsCnt samples which corresponds to EpochsCnt iterations being reported. By default, it performs exactly the same number of iterations as it reports. However, it will perform more iterations than it reports if using a burn-in phase (discards initial samples that are too influenced by the initial state) and by specifying a thinning factor greater than 1 (helps to combat autocorrelations). NOTE: for consistency with the rest of the library this move type requires PopSize>=N+1. However, it also has a special requirement PopSize>=4 that follows from the fact that each walker needs at least two other walkers to produce a DE proposal, and that we can use parallel moves (that need larger ensembles). For N=1 or N=2 it is possible to specify PopSize=N+1 that is less than 4. In order to simplify the algorithm, in this case we silently override selection with the stretch move. NOTE: it is recommended to specify PopSize and EpochsCnt and leave other parameters to their default values. INPUT PARAMETERS: State - structure that stores MCMC sampler state PopSize - ensemble size, PopSize>=N+1, recommended: >=2*N EpochsCnt- iterations count to be reported, >=1 Sigma - non-negative, standard deviation of a Gaussian used to randomly modify the proposal vector. Recommended values: about 1E-5. Zero value (or omitted) means that a default one is used. Gamma0 - the mean stretch factor for the proposal vector, >=0. Zero value means that a default value is used which is 2.38/sqrt(2N), as recommended by the original paper. -- ALGLIB -- Copyright 20.11.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetalgode(mcmcstate &state, const ae_int_t popsize, const ae_int_t epochscnt, const double sigma, const double gamma0, const xparams _xparams = alglib::xdefault); void mcmcsetalgode(mcmcstate &state, const ae_int_t popsize, const ae_int_t epochscnt, const xparams _xparams = alglib::xdefault);
mcmcsetalgodesnooker function/************************************************************************* This function sets MCMC algorithm to Goodman-Weare (ensemble MCMC) with the specified ensemble size and number of iterations being reported. Uses DE move with snooker update, as defined in 'Differential Evolution Markov Chain with snooker updater and fewer chains' by Cajo J.F. ter Braak and Jasper A. Vrugt. NOTE: the sampler always reports PopSize*EpochsCnt samples which corresponds to EpochsCnt iterations being reported. By default, it performs exactly the same number of iterations as it reports. However, it will perform more iterations than it reports if using a burn-in phase (discards initial samples that are too influenced by the initial state) and by specifying a thinning factor greater than 1 (helps to combat autocorrelations). NOTE: for consistency with the rest of the library this move type requires PopSize>=N+1. However, it also has a special requirement PopSize>=6 that follows from the fact that each update needs at least three other walkers to produce a DE proposal, and that we can use parallel moves (that need larger ensembles). In order to simplify the algorithm, if N+1<=PopSize<6, we silently override selection with the stretch move. NOTE: it is recommended to specify PopSize and EpochsCnt and leave other parameters to their default values. INPUT PARAMETERS: State - structure that stores MCMC sampler state PopSize - ensemble size, PopSize>=N+1, recommended: >=2*N EpochsCnt- iterations count to be reported, >=1 Gamma0 - the mean stretch factor for the proposal vector, >=0. Zero value means that a default value is used which is 2.38/sqrt(2), as recommended by the original paper. -- ALGLIB -- Copyright 20.11.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetalgodesnooker(mcmcstate &state, const ae_int_t popsize, const ae_int_t epochscnt, const double gamma0, const xparams _xparams = alglib::xdefault); void mcmcsetalgodesnooker(mcmcstate &state, const ae_int_t popsize, const ae_int_t epochscnt, const xparams _xparams = alglib::xdefault);
mcmcsetalgogaussian function/************************************************************************* This function sets MCMC algorithm to Goodman-Weare (ensemble MCMC) with the specified ensemble size and number of iterations being reported. Uses Gaussian random walk, an ensemble of PopSize completely independent walkers. NOTE: the sampler always reports PopSize*EpochsCnt samples which corresponds to EpochsCnt iterations being reported. By default, it performs exactly the same number of iterations as it reports. However, it will perform more iterations than it reports if using a burn-in phase (discards initial samples that are too influenced by the initial state) and by specifying a thinning factor greater than 1 (helps to combat autocorrelations). NOTE: this move is special because it can work with any ensemble size, including PopSize=1 (most other moves need at least 4, 5 or 6 walkers in the ensemble). Other moves will throw an exception if called with PopSize<N+1. INPUT PARAMETERS: State - structure that stores MCMC sampler state PopSize - ensemble size, PopSize>=1. EpochsCnt- iterations count to be reported, >=1 C - array[N,N], a positive definite covariance matrix. Walker position is perturbed with Gaussian perturbation with covariance C. IsUpper - if IsUpper=True, only upper triangle of C is used (the lower one is ignored). Otherwise, only lower triangle is used. -- ALGLIB -- Copyright 20.11.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetalgogaussian(mcmcstate &state, const ae_int_t popsize, const ae_int_t epochscnt, const real_2d_array &c, const bool isupper, const xparams _xparams = alglib::xdefault);
mcmcsetalgogoodmanweare function/************************************************************************* Same as mcmcsetalgostretch(). *************************************************************************/void mcmcsetalgogoodmanweare(mcmcstate &state, const ae_int_t popsize, const ae_int_t epochscnt, const xparams _xparams = alglib::xdefault);
Examples: [1]
mcmcsetalgostretch function/************************************************************************* This function sets MCMC algorithm to Goodman-Weare ( ensemble MCMC) with the specified ensemble size and number of iterations being reported. Uses stretch move, as defined in 'Ensemble samplers with affine invariance', Goodman and Weare, 2010. NOTE: the sampler always reports PopSize*EpochsCnt samples which corresponds to EpochsCnt iterations being reported. By default, it performs exactly the same number of iterations as it reports. However, it will perform more iterations than it reports if using a burn-in phase (discards initial samples that are too influenced by the initial state) and by specifying a thinning factor greater than 1 (helps to combat autocorrelations). INPUT PARAMETERS: State - structure that stores MCMC sampler state PopSize - ensemble size, PopSize>=N+1, recommended: >=2*N EpochsCnt- iterations count to be reported, >=1 -- ALGLIB -- Copyright 20.01.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetalgostretch(mcmcstate &state, const ae_int_t popsize, const ae_int_t epochscnt, const xparams _xparams = alglib::xdefault);
mcmcsetalgowalk function/************************************************************************* This function sets MCMC algorithm to Goodman-Weare ( ensemble MCMC) with the specified ensemble size and number of iterations being reported. Uses walk move, as defined in 'Ensemble samplers with affine invariance', Goodman and Weare, 2010. NOTE: the sampler always reports PopSize*EpochsCnt samples which corresponds to EpochsCnt iterations being reported. By default, it performs exactly the same number of iterations as it reports. However, it will perform more iterations than it reports if using a burn-in phase (discards initial samples that are too influenced by the initial state) and by specifying a thinning factor greater than 1 (helps to combat autocorrelations). NOTE: for consistency with the rest of the library this move type requires PopSize>=N+1. However, it also has a special requirement PopSize>=4 that follows from the fact that each walker needs at least two helpers, and that we can use parallel moves. For N=1 or N=2 it is possible to specify PopSize=N+1 that is less than 4. In order to simplify the algorithm, in this case we silently override selection with the stretch move. INPUT PARAMETERS: State - structure that stores MCMC sampler state PopSize - ensemble size, PopSize>=N+1, recommended: >=2*N EpochsCnt- iterations count to be reported, >=1 HelpersCnt- helpers count, >=2. Number of helpers used to generate proposal. Recommended values: some small number like 3-5. It is possible to specify HelpersCnt=PopSize, but for large populations it will result in proposal generation overhead growing as O(N*PopSize^2). Values larger than PopSize will be silently truncated to PopSize. -- ALGLIB -- Copyright 20.11.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetalgowalk(mcmcstate &state, const ae_int_t popsize, const ae_int_t epochscnt, const ae_int_t helperscnt, const xparams _xparams = alglib::xdefault);
mcmcsetburninlength function/************************************************************************* This function sets number of additional initial iterations (in addition to EpochsCnt) that will be performed and discarded (not stored into the report sample), so called 'burn-in length'. In total, BurnInLen+EpochsCnt iterations will be performed, with initial BurnInLen ones being used solely to help MCMC spread walkers according to the density of the function being sampled. INPUT PARAMETERS: State - structure that stores MCMC sampler state BurnInLen - burn-in length, >=0 -- ALGLIB -- Copyright 20.01.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetburninlength(mcmcstate &state, const ae_int_t burninlen, const xparams _xparams = alglib::xdefault);
Examples: [1]
mcmcsetfixedtemperatureladder function/************************************************************************* This function activates parallel tempering with the fixed temperature ladder. Parallel tempering is intended for sampling of multimodal distributions, with the T=1 corresponding to sampling of the original distribution (what you get as result), and higher temperatures corresponding to smoothed versions of the distribution, helping the sampler to reach otherwise unreachable remote peaks. INPUT PARAMETERS: State - structure stores algorithm state T - array[NTemp], T[0]=1, T[I+1]>T[I], sampling temperatures. If the first element of T is different from 1, or temperatures are not strictly increasing, an exception is raised NTemp - >=1, temperature ladder height -- ALGLIB -- Copyright 15.05.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetfixedtemperatureladder(mcmcstate &state, const real_1d_array &t, const ae_int_t ntemp, const xparams _xparams = alglib::xdefault);
mcmcsetladderadaptationrate function/************************************************************************* This function controls adaptation rate of the temperature ladder used by adaptive parallel tempering algorithms. The sampler changes the logarithmic difference between temperatures in the ladder ln(T[i+1]-T[i]) as a product of different between swap accept rates A[i]-A[i+1] and current adaptation rate, which is nu0/(1+iteridx/tau). Here nu0 is an initial adaptation rate that similar to stochastic gradient descent learning rate. Recommended values 0.01-0.1. And tau is a learning rate decay time, depending on the problem it can be 100 or 1000. The MCMC sampler uses some default values for these parameters, but they can change in future versions without notice. This function has no effect when adaptive tempering is not active. INPUT PARAMETERS: State - structure stores algorithm state Nu0 - initial learning rate, >=0. Zero value effectively turns off adaptation. Tau - characteristic decay time, >=0. Zero value effectively turns off adaptation. -- ALGLIB -- Copyright 15.05.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetladderadaptationrate(mcmcstate &state, const double nu0, const double tau, const xparams _xparams = alglib::xdefault);
mcmcsetsartemperatureladder function/************************************************************************* This function activates parallel tempering with the adaptive temperature ladder using uniform Swap Acceptance Rate (SAR) proposal. Parallel tempering is intended for sampling of multimodal distributions, with the T=1 corresponding to sampling of the original distribution (what you get as result), and higher temperatures corresponding to smoothed versions of the distribution, helping the sampler to reach otherwise unreachable remote peaks. The function accepts the hottest temperature in the ladder TMax, as well as ladder height NTemp>=1. You can control adaptation rate wuth mcmcsetladderadaptationrate() function. INPUT PARAMETERS: State - structure stores algorithm state TMax - initial value of the maximum temperature in the ladder, TMax>1 (strictly) NTemp - >=1, temperature ladder height: * NTemp=1 means that no temperature ladder is actually used * NTemp=2 means that we have a ladder with temperatures [1,TMax] and no adaptation * NTemp>2 means that we have a ladder with T[0]=1 and T[NTemp-1]=TMax, and adaptive temperatures between them. -- ALGLIB -- Copyright 15.05.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetsartemperatureladder(mcmcstate &state, const double tmax, const ae_int_t ntemp, const xparams _xparams = alglib::xdefault);
mcmcsetscale function/************************************************************************* This function sets per-variable scaling coefficients for MCMC sampler. Present version of the MCMC sampler uses per-variable scales during initial popilation generation: an initial point X0 is perturbed with random noise, whose per-variable magnitude is XStdDev*S[I]. Future versions of the sampler may use scales for other purposes too, but are likely to do so in a backward-compatible manner. INPUT PARAMETERS: State - structure stores algorithm state S - array[N], non-zero scaling coefficients S[i] may be negative, sign doesn't matter. -- ALGLIB -- Copyright 15.05.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetscale(mcmcstate &state, const real_1d_array &s, const xparams _xparams = alglib::xdefault);
mcmcsetseed function/************************************************************************* This function sets the seed which is used to initialize internal RNG. By default, a deterministic seed is used - same for each run of the sampler. It means that the same sampling decisions are taken every time. If you specify a non-deterministic seed value, then the sampler may return slightly different results after each run. INPUT PARAMETERS: S - sampler state Seed - seed: * positive values = use deterministic seed for each run of algorithms which depend on random initialization * zero or negative values = use non-deterministic seed -- ALGLIB -- Copyright 08.06.2017 by Bochkanov Sergey *************************************************************************/void mcmcsetseed(mcmcstate &s, const ae_int_t seed, const xparams _xparams = alglib::xdefault);
mcmcsetthinningfactor function/************************************************************************* This function sets thinning factor: ThinBy*EpochsCnt iterations will be performed (after the optional burn-in phase), with every ThinBy-th iteration being saved and the rest being discarded. This option helps to avoid storing highly correlated samples. INPUT PARAMETERS: State - structure that stores MCMC sampler state ThinBy - thinning factor, >=1 -- ALGLIB -- Copyright 20.01.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetthinningfactor(mcmcstate &state, const ae_int_t thinby, const xparams _xparams = alglib::xdefault);
mcmcsetxrep function/************************************************************************* This function turns on/off reporting. INPUT PARAMETERS: State - structure which stores sampler state NeedXRep- whether iteration reports are needed or not If NeedXRep is True, the algorithm will call rep() callback function if it was provided to mcmcrun(). NOTE: due to ALGLIB conventions regarding report callbacks, the sampler passes two parameters to the rep() callback - an 1D floating point array, and a scalar floating-point value. In nonlinear optimizers these parameters are used to report current point/objective, but it makes little sense in the context of MCMC. Because of that, MCMC sampler sets the first parameter to be a zero-initialized single-element array, and the second (scalar) parameter is set to zero. -- ALGLIB -- Copyright 25.02.2025 by Bochkanov Sergey *************************************************************************/void mcmcsetxrep(mcmcstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "statistics.h"
using namespace alglib;
void logprob1_func(const real_1d_array &x, double &func, void *ptr)
{
//
// This callback calculates
//
// log_p(x,y) = -0.5*(100*(x+1)^2 + (y-1)^2)
//
// which corresponds to
//
// p(x,y)=exp(-0.5*(100*(x+1)^2 + (y-1)^2))
//
// An additional parameter ptr may be used to pass some data to this
// callback (if you pass some pointer value as ptr parameter of the
// optimizer method, it will forward this pointer to the callback).
//
func = -0.5*(100*pow(x[0]+1,2) + pow(x[1]-1,2));
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates sampling of a function given by log-probability
//
// log_p(x,y) = -0.5*(100*(x+1)^2 + (y-1)^2)
//
// which corresponds to
//
// p(x,y)=exp(-0.5*(100*(x+1)^2 + (y-1)^2))
//
// using ensemble method with the initial point (x,y)=[1,1], and initial
// population being randomly distributed around it with standard deviation
// xstddev=0.1
//
// A burn-in phase with 50 iterations is used to smooth out influence of
// initial point/population.
//
// First, we create and configure the sampler.
//
real_1d_array x0 = "[1,1]";
mcmcstate state;
ae_int_t popsize = 10;
ae_int_t epochscnt = 100;
ae_int_t burnin = 50;
double xstddev = 0.1;
mcmccreate1(x0, xstddev, state);
mcmcsetalgogoodmanweare(state, popsize, epochscnt);
mcmcsetburninlength(state, burnin);
//
// After the sampler was configured, we can run it and extract results.
// The results are returned as a 2D matrix with dimensions [epochscnt*popsize,n].
//
// NOTE: it is also possible to pass a rep() callback to mcmcrun(), and to
// retrieve interim results from the sampler while it is still running.
// It can be used to check convergence or just to peek into progress.
//
mcmcreport rep;
real_2d_array sample;
ae_int_t samplesize;
alglib::mcmcrun(state, logprob1_func);
mcmcresults(state, sample, samplesize, rep);
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
mcpd subpackage| mcpd_simple1 | Simple unconstrained MCPD model (no entry/exit states) | |
| mcpd_simple2 | Simple MCPD model (no entry/exit states) with equality constraints |
mcpdreport class/************************************************************************* This structure is a MCPD training report: InnerIterationsCount - number of inner iterations of the underlying optimization algorithm OuterIterationsCount - number of outer iterations of the underlying optimization algorithm NFEV - number of merit function evaluations TerminationType - termination type (same as for MinBLEIC optimizer, positive values denote success, negative ones - failure) -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/class mcpdreport { public: mcpdreport(); mcpdreport(const mcpdreport &rhs); mcpdreport& operator=(const mcpdreport &rhs); virtual ~mcpdreport(); ae_int_t inneriterationscount; ae_int_t outeriterationscount; ae_int_t nfev; ae_int_t terminationtype; };
mcpdstate class/************************************************************************* This structure is a MCPD (Markov Chains for Population Data) solver. You should use ALGLIB functions in order to work with this object. -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/class mcpdstate { public: mcpdstate(); mcpdstate(const mcpdstate &rhs); mcpdstate& operator=(const mcpdstate &rhs); virtual ~mcpdstate(); };
mcpdaddbc function/************************************************************************* This function is used to add bound constraints on the elements of the transition matrix P. MCPD solver has four types of constraints which can be placed on P: * user-specified equality constraints (optional) * user-specified bound constraints (optional) * user-specified general linear constraints (optional) * basic constraints (always present): * non-negativity: P[i,j]>=0 * consistency: every column of P sums to 1.0 Final constraints which are passed to the underlying optimizer are calculated as intersection of all present constraints. For example, you may specify boundary constraint on P[0,0] and equality one: 0.1<=P[0,0]<=0.9 P[0,0]=0.5 Such combination of constraints will be silently reduced to their intersection, which is P[0,0]=0.5. This function can be used to ADD bound constraint for one element of P without changing constraints for other elements. You can also use MCPDSetBC() function which allows to place bound constraints on arbitrary subset of elements of P. Set of constraints is specified by BndL/BndU matrices, which may contain arbitrary combination of finite numbers or infinities (like -INF<x<=0.5 or 0.1<=x<+INF). These functions (MCPDSetBC and MCPDAddBC) interact as follows: * there is internal matrix of bound constraints which is stored in the MCPD solver * MCPDSetBC() replaces this matrix by another one (SET) * MCPDAddBC() modifies one element of this matrix and leaves other ones unchanged (ADD) * thus MCPDAddBC() call preserves all modifications done by previous calls, while MCPDSetBC() completely discards all changes done to the equality constraints. INPUT PARAMETERS: S - solver I - row index of element being constrained J - column index of element being constrained BndL - lower bound BndU - upper bound -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdaddbc(mcpdstate &s, const ae_int_t i, const ae_int_t j, const double bndl, const double bndu, const xparams _xparams = alglib::xdefault);
mcpdaddec function/************************************************************************* This function is used to add equality constraints on the elements of the transition matrix P. MCPD solver has four types of constraints which can be placed on P: * user-specified equality constraints (optional) * user-specified bound constraints (optional) * user-specified general linear constraints (optional) * basic constraints (always present): * non-negativity: P[i,j]>=0 * consistency: every column of P sums to 1.0 Final constraints which are passed to the underlying optimizer are calculated as intersection of all present constraints. For example, you may specify boundary constraint on P[0,0] and equality one: 0.1<=P[0,0]<=0.9 P[0,0]=0.5 Such combination of constraints will be silently reduced to their intersection, which is P[0,0]=0.5. This function can be used to ADD equality constraint for one element of P without changing constraints for other elements. You can also use MCPDSetEC() function which allows you to specify arbitrary set of equality constraints in one call. These functions (MCPDSetEC and MCPDAddEC) interact as follows: * there is internal matrix of equality constraints which is stored in the MCPD solver * MCPDSetEC() replaces this matrix by another one (SET) * MCPDAddEC() modifies one element of this matrix and leaves other ones unchanged (ADD) * thus MCPDAddEC() call preserves all modifications done by previous calls, while MCPDSetEC() completely discards all changes done to the equality constraints. INPUT PARAMETERS: S - solver I - row index of element being constrained J - column index of element being constrained C - value (constraint for P[I,J]). Can be either NAN (no constraint) or finite value from [0,1]. NOTES: 1. infinite values of C will lead to exception being thrown. Values less than 0.0 or greater than 1.0 will lead to error code being returned after call to MCPDSolve(). -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdaddec(mcpdstate &s, const ae_int_t i, const ae_int_t j, const double c, const xparams _xparams = alglib::xdefault);
Examples: [1]
mcpdaddtrack function/************************************************************************* This function is used to add a track - sequence of system states at the different moments of its evolution. You may add one or several tracks to the MCPD solver. In case you have several tracks, they won't overwrite each other. For example, if you pass two tracks, A1-A2-A3 (system at t=A+1, t=A+2 and t=A+3) and B1-B2-B3, then solver will try to model transitions from t=A+1 to t=A+2, t=A+2 to t=A+3, t=B+1 to t=B+2, t=B+2 to t=B+3. But it WONT mix these two tracks - i.e. it wont try to model transition from t=A+3 to t=B+1. INPUT PARAMETERS: S - solver XY - track, array[K,N]: * I-th row is a state at t=I * elements of XY must be non-negative (exception will be thrown on negative elements) K - number of points in a track * if given, only leading K rows of XY are used * if not given, automatically determined from size of XY NOTES: 1. Track may contain either proportional or population data: * with proportional data all rows of XY must sum to 1.0, i.e. we have proportions instead of absolute population values * with population data rows of XY contain population counts and generally do not sum to 1.0 (although they still must be non-negative) -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdaddtrack(mcpdstate &s, const real_2d_array &xy, const ae_int_t k, const xparams _xparams = alglib::xdefault); void mcpdaddtrack(mcpdstate &s, const real_2d_array &xy, const xparams _xparams = alglib::xdefault);
mcpdcreate function/************************************************************************* DESCRIPTION: This function creates MCPD (Markov Chains for Population Data) solver. This solver can be used to find transition matrix P for N-dimensional prediction problem where transition from X[i] to X[i+1] is modelled as X[i+1] = P*X[i] where X[i] and X[i+1] are N-dimensional population vectors (components of each X are non-negative), and P is a N*N transition matrix (elements of P are non-negative, each column sums to 1.0). Such models arise when when: * there is some population of individuals * individuals can have different states * individuals can transit from one state to another * population size is constant, i.e. there is no new individuals and no one leaves population * you want to model transitions of individuals from one state into another USAGE: Here we give very brief outline of the MCPD. We strongly recommend you to read examples in the ALGLIB Reference Manual and to read ALGLIB User Guide on data analysis which is available at http://www.alglib.net/dataanalysis/ 1. User initializes algorithm state with MCPDCreate() call 2. User adds one or more tracks - sequences of states which describe evolution of a system being modelled from different starting conditions 3. User may add optional boundary, equality and/or linear constraints on the coefficients of P by calling one of the following functions: * MCPDSetEC() to set equality constraints * MCPDSetBC() to set bound constraints * MCPDSetLC() to set linear constraints 4. Optionally, user may set custom weights for prediction errors (by default, algorithm assigns non-equal, automatically chosen weights for errors in the prediction of different components of X). It can be done with a call of MCPDSetPredictionWeights() function. 5. User calls MCPDSolve() function which takes algorithm state and pointer (delegate, etc.) to callback function which calculates F/G. 6. User calls MCPDResults() to get solution INPUT PARAMETERS: N - problem dimension, N>=1 OUTPUT PARAMETERS: State - structure stores algorithm state -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdcreate(const ae_int_t n, mcpdstate &s, const xparams _xparams = alglib::xdefault);
mcpdcreateentry function/************************************************************************* DESCRIPTION: This function is a specialized version of MCPDCreate() function, and we recommend you to read comments for this function for general information about MCPD solver. This function creates MCPD (Markov Chains for Population Data) solver for "Entry-state" model, i.e. model where transition from X[i] to X[i+1] is modelled as X[i+1] = P*X[i] where X[i] and X[i+1] are N-dimensional state vectors P is a N*N transition matrix and one selected component of X[] is called "entry" state and is treated in a special way: system state always transits from "entry" state to some another state system state can not transit from any state into "entry" state Such conditions basically mean that row of P which corresponds to "entry" state is zero. Such models arise when: * there is some population of individuals * individuals can have different states * individuals can transit from one state to another * population size is NOT constant - at every moment of time there is some (unpredictable) amount of "new" individuals, which can transit into one of the states at the next turn, but still no one leaves population * you want to model transitions of individuals from one state into another * but you do NOT want to predict amount of "new" individuals because it does not depends on individuals already present (hence system can not transit INTO entry state - it can only transit FROM it). This model is discussed in more details in the ALGLIB User Guide (see http://www.alglib.net/dataanalysis/ for more data). INPUT PARAMETERS: N - problem dimension, N>=2 EntryState- index of entry state, in 0..N-1 OUTPUT PARAMETERS: State - structure stores algorithm state -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdcreateentry(const ae_int_t n, const ae_int_t entrystate, mcpdstate &s, const xparams _xparams = alglib::xdefault);
mcpdcreateentryexit function/************************************************************************* DESCRIPTION: This function is a specialized version of MCPDCreate() function, and we recommend you to read comments for this function for general information about MCPD solver. This function creates MCPD (Markov Chains for Population Data) solver for "Entry-Exit-states" model, i.e. model where transition from X[i] to X[i+1] is modelled as X[i+1] = P*X[i] where X[i] and X[i+1] are N-dimensional state vectors P is a N*N transition matrix one selected component of X[] is called "entry" state and is treated in a special way: system state always transits from "entry" state to some another state system state can not transit from any state into "entry" state and another one component of X[] is called "exit" state and is treated in a special way too: system state can transit from any state into "exit" state system state can not transit from "exit" state into any other state transition operator discards "exit" state (makes it zero at each turn) Such conditions basically mean that: row of P which corresponds to "entry" state is zero column of P which corresponds to "exit" state is zero Multiplication by such P may decrease sum of vector components. Such models arise when: * there is some population of individuals * individuals can have different states * individuals can transit from one state to another * population size is NOT constant * at every moment of time there is some (unpredictable) amount of "new" individuals, which can transit into one of the states at the next turn * some individuals can move (predictably) into "exit" state and leave population at the next turn * you want to model transitions of individuals from one state into another, including transitions from the "entry" state and into the "exit" state. * but you do NOT want to predict amount of "new" individuals because it does not depends on individuals already present (hence system can not transit INTO entry state - it can only transit FROM it). This model is discussed in more details in the ALGLIB User Guide (see http://www.alglib.net/dataanalysis/ for more data). INPUT PARAMETERS: N - problem dimension, N>=2 EntryState- index of entry state, in 0..N-1 ExitState- index of exit state, in 0..N-1 OUTPUT PARAMETERS: State - structure stores algorithm state -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdcreateentryexit(const ae_int_t n, const ae_int_t entrystate, const ae_int_t exitstate, mcpdstate &s, const xparams _xparams = alglib::xdefault);
mcpdcreateexit function/************************************************************************* DESCRIPTION: This function is a specialized version of MCPDCreate() function, and we recommend you to read comments for this function for general information about MCPD solver. This function creates MCPD (Markov Chains for Population Data) solver for "Exit-state" model, i.e. model where transition from X[i] to X[i+1] is modelled as X[i+1] = P*X[i] where X[i] and X[i+1] are N-dimensional state vectors P is a N*N transition matrix and one selected component of X[] is called "exit" state and is treated in a special way: system state can transit from any state into "exit" state system state can not transit from "exit" state into any other state transition operator discards "exit" state (makes it zero at each turn) Such conditions basically mean that column of P which corresponds to "exit" state is zero. Multiplication by such P may decrease sum of vector components. Such models arise when: * there is some population of individuals * individuals can have different states * individuals can transit from one state to another * population size is NOT constant - individuals can move into "exit" state and leave population at the next turn, but there are no new individuals * amount of individuals which leave population can be predicted * you want to model transitions of individuals from one state into another (including transitions into the "exit" state) This model is discussed in more details in the ALGLIB User Guide (see http://www.alglib.net/dataanalysis/ for more data). INPUT PARAMETERS: N - problem dimension, N>=2 ExitState- index of exit state, in 0..N-1 OUTPUT PARAMETERS: State - structure stores algorithm state -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdcreateexit(const ae_int_t n, const ae_int_t exitstate, mcpdstate &s, const xparams _xparams = alglib::xdefault);
mcpdresults function/************************************************************************* MCPD results INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: P - array[N,N], transition matrix Rep - optimization report. You should check Rep.TerminationType in order to distinguish successful termination from unsuccessful one. Speaking short, positive values denote success, negative ones are failures. More information about fields of this structure can be found in the comments on MCPDReport datatype. -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdresults(const mcpdstate &s, real_2d_array &p, mcpdreport &rep, const xparams _xparams = alglib::xdefault);
mcpdsetbc function/************************************************************************* This function is used to add bound constraints on the elements of the transition matrix P. MCPD solver has four types of constraints which can be placed on P: * user-specified equality constraints (optional) * user-specified bound constraints (optional) * user-specified general linear constraints (optional) * basic constraints (always present): * non-negativity: P[i,j]>=0 * consistency: every column of P sums to 1.0 Final constraints which are passed to the underlying optimizer are calculated as intersection of all present constraints. For example, you may specify boundary constraint on P[0,0] and equality one: 0.1<=P[0,0]<=0.9 P[0,0]=0.5 Such combination of constraints will be silently reduced to their intersection, which is P[0,0]=0.5. This function can be used to place bound constraints on arbitrary subset of elements of P. Set of constraints is specified by BndL/BndU matrices, which may contain arbitrary combination of finite numbers or infinities (like -INF<x<=0.5 or 0.1<=x<+INF). You can also use MCPDAddBC() function which allows to ADD bound constraint for one element of P without changing constraints for other elements. These functions (MCPDSetBC and MCPDAddBC) interact as follows: * there is internal matrix of bound constraints which is stored in the MCPD solver * MCPDSetBC() replaces this matrix by another one (SET) * MCPDAddBC() modifies one element of this matrix and leaves other ones unchanged (ADD) * thus MCPDAddBC() call preserves all modifications done by previous calls, while MCPDSetBC() completely discards all changes done to the equality constraints. INPUT PARAMETERS: S - solver BndL - lower bounds constraints, array[N,N]. Elements of BndL can be finite numbers or -INF. BndU - upper bounds constraints, array[N,N]. Elements of BndU can be finite numbers or +INF. -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdsetbc(mcpdstate &s, const real_2d_array &bndl, const real_2d_array &bndu, const xparams _xparams = alglib::xdefault);
mcpdsetec function/************************************************************************* This function is used to add equality constraints on the elements of the transition matrix P. MCPD solver has four types of constraints which can be placed on P: * user-specified equality constraints (optional) * user-specified bound constraints (optional) * user-specified general linear constraints (optional) * basic constraints (always present): * non-negativity: P[i,j]>=0 * consistency: every column of P sums to 1.0 Final constraints which are passed to the underlying optimizer are calculated as intersection of all present constraints. For example, you may specify boundary constraint on P[0,0] and equality one: 0.1<=P[0,0]<=0.9 P[0,0]=0.5 Such combination of constraints will be silently reduced to their intersection, which is P[0,0]=0.5. This function can be used to place equality constraints on arbitrary subset of elements of P. Set of constraints is specified by EC, which may contain either NAN's or finite numbers from [0,1]. NAN denotes absence of constraint, finite number denotes equality constraint on specific element of P. You can also use MCPDAddEC() function which allows to ADD equality constraint for one element of P without changing constraints for other elements. These functions (MCPDSetEC and MCPDAddEC) interact as follows: * there is internal matrix of equality constraints which is stored in the MCPD solver * MCPDSetEC() replaces this matrix by another one (SET) * MCPDAddEC() modifies one element of this matrix and leaves other ones unchanged (ADD) * thus MCPDAddEC() call preserves all modifications done by previous calls, while MCPDSetEC() completely discards all changes done to the equality constraints. INPUT PARAMETERS: S - solver EC - equality constraints, array[N,N]. Elements of EC can be either NAN's or finite numbers from [0,1]. NAN denotes absence of constraints, while finite value denotes equality constraint on the corresponding element of P. NOTES: 1. infinite values of EC will lead to exception being thrown. Values less than 0.0 or greater than 1.0 will lead to error code being returned after call to MCPDSolve(). -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdsetec(mcpdstate &s, const real_2d_array &ec, const xparams _xparams = alglib::xdefault);
mcpdsetlc function/************************************************************************* This function is used to set linear equality/inequality constraints on the elements of the transition matrix P. This function can be used to set one or several general linear constraints on the elements of P. Two types of constraints are supported: * equality constraints * inequality constraints (both less-or-equal and greater-or-equal) Coefficients of constraints are specified by matrix C (one of the parameters). One row of C corresponds to one constraint. Because transition matrix P has N*N elements, we need N*N columns to store all coefficients (they are stored row by row), and one more column to store right part - hence C has N*N+1 columns. Constraint kind is stored in the CT array. Thus, I-th linear constraint is P[0,0]*C[I,0] + P[0,1]*C[I,1] + .. + P[0,N-1]*C[I,N-1] + + P[1,0]*C[I,N] + P[1,1]*C[I,N+1] + ... + + P[N-1,N-1]*C[I,N*N-1] ?=? C[I,N*N] where ?=? can be either "=" (CT[i]=0), "<=" (CT[i]<0) or ">=" (CT[i]>0). Your constraint may involve only some subset of P (less than N*N elements). For example it can be something like P[0,0] + P[0,1] = 0.5 In this case you still should pass matrix with N*N+1 columns, but all its elements (except for C[0,0], C[0,1] and C[0,N*N-1]) will be zero. INPUT PARAMETERS: S - solver C - array[K,N*N+1] - coefficients of constraints (see above for complete description) CT - array[K] - constraint types (see above for complete description) K - number of equality/inequality constraints, K>=0: * if given, only leading K elements of C/CT are used * if not given, automatically determined from sizes of C/CT -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdsetlc(mcpdstate &s, const real_2d_array &c, const integer_1d_array &ct, const ae_int_t k, const xparams _xparams = alglib::xdefault); void mcpdsetlc(mcpdstate &s, const real_2d_array &c, const integer_1d_array &ct, const xparams _xparams = alglib::xdefault);
mcpdsetpredictionweights function/************************************************************************* This function is used to change prediction weights MCPD solver scales prediction errors as follows Error(P) = ||W*(y-P*x)||^2 where x is a system state at time t y is a system state at time t+1 P is a transition matrix W is a diagonal scaling matrix By default, weights are chosen in order to minimize relative prediction error instead of absolute one. For example, if one component of state is about 0.5 in magnitude and another one is about 0.05, then algorithm will make corresponding weights equal to 2.0 and 20.0. INPUT PARAMETERS: S - solver PW - array[N], weights: * must be non-negative values (exception will be thrown otherwise) * zero values will be replaced by automatically chosen values -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdsetpredictionweights(mcpdstate &s, const real_1d_array &pw, const xparams _xparams = alglib::xdefault);
mcpdsetprior function/************************************************************************* This function allows to set prior values used for regularization of your problem. By default, regularizing term is equal to r*||P-prior_P||^2, where r is a small non-zero value, P is transition matrix, prior_P is identity matrix, ||X||^2 is a sum of squared elements of X. This function allows you to change prior values prior_P. You can also change r with MCPDSetTikhonovRegularizer() function. INPUT PARAMETERS: S - solver PP - array[N,N], matrix of prior values: 1. elements must be real numbers from [0,1] 2. columns must sum to 1.0. First property is checked (exception is thrown otherwise), while second one is not checked/enforced. -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdsetprior(mcpdstate &s, const real_2d_array &pp, const xparams _xparams = alglib::xdefault);
mcpdsettikhonovregularizer function/************************************************************************* This function allows to tune amount of Tikhonov regularization being applied to your problem. By default, regularizing term is equal to r*||P-prior_P||^2, where r is a small non-zero value, P is transition matrix, prior_P is identity matrix, ||X||^2 is a sum of squared elements of X. This function allows you to change coefficient r. You can also change prior values with MCPDSetPrior() function. INPUT PARAMETERS: S - solver V - regularization coefficient, finite non-negative value. It is not recommended to specify zero value unless you are pretty sure that you want it. -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdsettikhonovregularizer(mcpdstate &s, const double v, const xparams _xparams = alglib::xdefault);
mcpdsolve function/************************************************************************* This function is used to start solution of the MCPD problem. After return from this function, you can use MCPDResults() to get solution and completion code. -- ALGLIB -- Copyright 23.05.2010 by Bochkanov Sergey *************************************************************************/void mcpdsolve(mcpdstate &s, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// The very simple MCPD example
//
// We have a loan portfolio. Our loans can be in one of two states:
// * normal loans ("good" ones)
// * past due loans ("bad" ones)
//
// We assume that:
// * loans can transition from any state to any other state. In
// particular, past due loan can become "good" one at any moment
// with same (fixed) probability. Not realistic, but it is toy example :)
// * portfolio size does not change over time
//
// Thus, we have following model
// state_new = P*state_old
// where
// ( p00 p01 )
// P = ( )
// ( p10 p11 )
//
// We want to model transitions between these two states using MCPD
// approach (Markov Chains for Proportional/Population Data), i.e.
// to restore hidden transition matrix P using actual portfolio data.
// We have:
// * poportional data, i.e. proportion of loans in the normal and past
// due states (not portfolio size measured in some currency, although
// it is possible to work with population data too)
// * two tracks, i.e. two sequences which describe portfolio
// evolution from two different starting states: [1,0] (all loans
// are "good") and [0.8,0.2] (only 80% of portfolio is in the "good"
// state)
//
mcpdstate s;
mcpdreport rep;
real_2d_array p;
real_2d_array track0 = "[[1.00000,0.00000],[0.95000,0.05000],[0.92750,0.07250],[0.91738,0.08263],[0.91282,0.08718]]";
real_2d_array track1 = "[[0.80000,0.20000],[0.86000,0.14000],[0.88700,0.11300],[0.89915,0.10085]]";
mcpdcreate(2, s);
mcpdaddtrack(s, track0);
mcpdaddtrack(s, track1);
mcpdsolve(s);
mcpdresults(s, p, rep);
//
// Hidden matrix P is equal to
// ( 0.95 0.50 )
// ( )
// ( 0.05 0.50 )
// which means that "good" loans can become "bad" with 5% probability,
// while "bad" loans will return to good state with 50% probability.
//
printf("%s\n", p.tostring(2).c_str()); // EXPECTED: [[0.95,0.50],[0.05,0.50]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "dataanalysis.h"
using namespace alglib;
int main(int argc, char **argv)
{
try
{
//
// Simple MCPD example
//
// We have a loan portfolio. Our loans can be in one of three states:
// * normal loans
// * past due loans
// * charged off loans
//
// We assume that:
// * normal loan can stay normal or become past due (but not charged off)
// * past due loan can stay past due, become normal or charged off
// * charged off loan will stay charged off for the rest of eternity
// * portfolio size does not change over time
// Not realistic, but it is toy example :)
//
// Thus, we have following model
// state_new = P*state_old
// where
// ( p00 p01 )
// P = ( p10 p11 )
// ( p21 1 )
// i.e. four elements of P are known a priori.
//
// Although it is possible (given enough data) to In order to enforce
// this property we set equality constraints on these elements.
//
// We want to model transitions between these two states using MCPD
// approach (Markov Chains for Proportional/Population Data), i.e.
// to restore hidden transition matrix P using actual portfolio data.
// We have:
// * poportional data, i.e. proportion of loans in the current and past
// due states (not portfolio size measured in some currency, although
// it is possible to work with population data too)
// * two tracks, i.e. two sequences which describe portfolio
// evolution from two different starting states: [1,0,0] (all loans
// are "good") and [0.8,0.2,0.0] (only 80% of portfolio is in the "good"
// state)
//
mcpdstate s;
mcpdreport rep;
real_2d_array p;
real_2d_array track0 = "[[1.000000,0.000000,0.000000],[0.950000,0.050000,0.000000],[0.927500,0.060000,0.012500],[0.911125,0.061375,0.027500],[0.896256,0.060900,0.042844]]";
real_2d_array track1 = "[[0.800000,0.200000,0.000000],[0.860000,0.090000,0.050000],[0.862000,0.065500,0.072500],[0.851650,0.059475,0.088875],[0.838805,0.057451,0.103744]]";
mcpdcreate(3, s);
mcpdaddtrack(s, track0);
mcpdaddtrack(s, track1);
mcpdaddec(s, 0, 2, 0.0);
mcpdaddec(s, 1, 2, 0.0);
mcpdaddec(s, 2, 2, 1.0);
mcpdaddec(s, 2, 0, 0.0);
mcpdsolve(s);
mcpdresults(s, p, rep);
//
// Hidden matrix P is equal to
// ( 0.95 0.50 )
// ( 0.05 0.25 )
// ( 0.25 1.00 )
// which means that "good" loans can become past due with 5% probability,
// while past due loans will become charged off with 25% probability or
// return back to normal state with 50% probability.
//
printf("%s\n", p.tostring(2).c_str()); // EXPECTED: [[0.95,0.50,0.00],[0.05,0.25,0.00],[0.00,0.25,1.00]]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
minbc subpackage| minbc_d_1 | Nonlinear optimization with box constraints | |
| minbc_numdiff | Nonlinear optimization with bound constraints and numerical differentiation |
minbcreport class/************************************************************************* This structure stores optimization report: * iterationscount number of iterations * nfev number of gradient evaluations * terminationtype termination type (see below) TERMINATION CODES terminationtype field contains completion code, which can be: -8 internal integrity control detected infinite or NAN values in function/gradient. Abnormal termination signalled. -3 inconsistent constraints. 1 relative function improvement is no more than EpsF. 2 relative step is no more than EpsX. 4 gradient norm is no more than EpsG 5 MaxIts steps was taken 7 stopping conditions are too stringent, further improvement is impossible, X contains best point found so far. 8 terminated by user who called minbcrequesttermination(). X contains point which was "current accepted" when termination request was submitted. *************************************************************************/class minbcreport { public: minbcreport(); minbcreport(const minbcreport &rhs); minbcreport& operator=(const minbcreport &rhs); virtual ~minbcreport(); ae_int_t iterationscount; ae_int_t nfev; ae_int_t varidx; ae_int_t terminationtype; };
minbcstate class/************************************************************************* This object stores nonlinear optimizer state. You should use functions provided by MinBC subpackage to work with this object *************************************************************************/class minbcstate { public: minbcstate(); minbcstate(const minbcstate &rhs); minbcstate& operator=(const minbcstate &rhs); virtual ~minbcstate(); };
minbccreate function/************************************************************************* BOX CONSTRAINED OPTIMIZATION WITH FAST ACTIVATION OF MULTIPLE BOX CONSTRAINTS DESCRIPTION: The subroutine minimizes function F(x) of N arguments subject to box constraints (with some of box constraints actually being equality ones). This optimizer uses algorithm similar to that of MinBLEIC (optimizer with general linear constraints), but presence of box-only constraints allows us to use faster constraint activation strategies. On large-scale problems, with multiple constraints active at the solution, this optimizer can be several times faster than BLEIC. REQUIREMENTS: * user must provide function value and gradient * starting point X0 must be feasible or not too far away from the feasible set * grad(f) must be Lipschitz continuous on a level set: L = { x : f(x)<=f(x0) } * function must be defined everywhere on the feasible set F USAGE: Constrained optimization if far more complex than the unconstrained one. Here we give very brief outline of the BC optimizer. We strongly recommend you to read examples in the ALGLIB Reference Manual and to read ALGLIB User Guide on optimization, which is available at http://www.alglib.net/optimization/ 1. User initializes algorithm state with MinBCCreate() call 2. USer adds box constraints by calling MinBCSetBC() function. 3. User sets stopping conditions with MinBCSetCond(). 4. User calls MinBCOptimize() function which takes algorithm state and pointer (delegate, etc.) to callback function which calculates F/G. 5. User calls MinBCResults() to get solution 6. Optionally user may call MinBCRestartFrom() to solve another problem with same N but another starting point. MinBCRestartFrom() allows to reuse already initialized structure. INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of X are used * if not given, automatically determined from size ofX X - starting point, array[N]: * it is better to set X to a feasible point * but X can be infeasible, in which case algorithm will try to find feasible point first, using X as initial approximation. OUTPUT PARAMETERS: State - structure stores algorithm state -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbccreate(const ae_int_t n, const real_1d_array &x, minbcstate &state, const xparams _xparams = alglib::xdefault); void minbccreate(const real_1d_array &x, minbcstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
minbccreatef function/************************************************************************* The subroutine is finite difference variant of MinBCCreate(). It uses finite differences in order to differentiate target function. Description below contains information which is specific to this function only. We recommend to read comments on MinBCCreate() in order to get more information about creation of BC optimizer. INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of X are used * if not given, automatically determined from size of X X - starting point, array[0..N-1]. DiffStep- differentiation step, >0 OUTPUT PARAMETERS: State - structure which stores algorithm state NOTES: 1. algorithm uses 4-point central formula for differentiation. 2. differentiation step along I-th axis is equal to DiffStep*S[I] where S[] is scaling vector which can be set by MinBCSetScale() call. 3. we recommend you to use moderate values of differentiation step. Too large step will result in too large truncation errors, while too small step will result in too large numerical errors. 1.0E-6 can be good value to start with. 4. Numerical differentiation is very inefficient - one gradient calculation needs 4*N function evaluations. This function will work for any N - either small (1...10), moderate (10...100) or large (100...). However, performance penalty will be too severe for any N's except for small ones. We should also say that code which relies on numerical differentiation is less robust and precise. CG needs exact gradient values. Imprecise gradient may slow down convergence, especially on highly nonlinear problems. Thus we recommend to use this function for fast prototyping on small- dimensional problems only, and to implement analytical gradient as soon as possible. -- ALGLIB -- Copyright 16.05.2011 by Bochkanov Sergey *************************************************************************/void minbccreatef(const ae_int_t n, const real_1d_array &x, const double diffstep, minbcstate &state, const xparams _xparams = alglib::xdefault); void minbccreatef(const real_1d_array &x, const double diffstep, minbcstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
minbciteration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool minbciteration(minbcstate &state, const xparams _xparams = alglib::xdefault);
minbcoptguardgradient function/************************************************************************* This function activates/deactivates verification of the user-supplied analytic gradient. Upon activation of this option OptGuard integrity checker performs numerical differentiation of your target function at the initial point (note: future versions may also perform check at the final point) and compares numerical gradient with analytic one provided by you. If difference is too large, an error flag is set and optimization session continues. After optimization session is over, you can retrieve the report which stores both gradients and specific components highlighted as suspicious by the OptGuard. The primary OptGuard report can be retrieved with minbcoptguardresults(). IMPORTANT: gradient check is a high-overhead option which will cost you about 3*N additional function evaluations. In many cases it may cost as much as the rest of the optimization session. YOU SHOULD NOT USE IT IN THE PRODUCTION CODE UNLESS YOU WANT TO CHECK DERIVATIVES PROVIDED BY SOME THIRD PARTY. NOTE: unlike previous incarnation of the gradient checking code, OptGuard does NOT interrupt optimization even if it discovers bad gradient. INPUT PARAMETERS: State - structure used to store algorithm state TestStep - verification step used for numerical differentiation: * TestStep=0 turns verification off * TestStep>0 activates verification You should carefully choose TestStep. Value which is too large (so large that function behavior is non- cubic at this scale) will lead to false alarms. Too short step will result in rounding errors dominating numerical derivative. You may use different step for different parameters by means of setting scale with minbcsetscale(). === EXPLANATION ========================================================== In order to verify gradient algorithm performs following steps: * two trial steps are made to X[i]-TestStep*S[i] and X[i]+TestStep*S[i], where X[i] is i-th component of the initial point and S[i] is a scale of i-th parameter * F(X) is evaluated at these trial points * we perform one more evaluation in the middle point of the interval * we build cubic model using function values and derivatives at trial points and we compare its prediction with actual value in the middle point -- ALGLIB -- Copyright 15.06.2014 by Bochkanov Sergey *************************************************************************/void minbcoptguardgradient(minbcstate &state, const double teststep, const xparams _xparams = alglib::xdefault);
minbcoptguardnonc1test0results function/************************************************************************* Detailed results of the OptGuard integrity check for nonsmoothness test #0 Nonsmoothness (non-C1) test #0 studies function values (not gradient!) obtained during line searches and monitors behavior of the directional derivative estimate. This test is less powerful than test #1, but it does not depend on the gradient values and thus it is more robust against artifacts introduced by numerical differentiation. Two reports are returned: * a "strongest" one, corresponding to line search which had highest value of the nonsmoothness indicator * a "longest" one, corresponding to line search which had more function evaluations, and thus is more detailed In both cases following fields are returned: * positive - is TRUE when test flagged suspicious point; FALSE if test did not notice anything (in the latter cases fields below are empty). * x0[], d[] - arrays of length N which store initial point and direction for line search (d[] can be normalized, but does not have to) * stp[], f[] - arrays of length CNT which store step lengths and function values at these points; f[i] is evaluated in x0+stp[i]*d. * stpidxa, stpidxb - we suspect that function violates C1 continuity between steps #stpidxa and #stpidxb (usually we have stpidxb=stpidxa+3, with most likely position of the violation between stpidxa+1 and stpidxa+2. ========================================================================== = SHORTLY SPEAKING: build a 2D plot of (stp,f) and look at it - you will = see where C1 continuity is violated. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: strrep - C1 test #0 "strong" report lngrep - C1 test #0 "long" report -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minbcoptguardnonc1test0results(const minbcstate &state, optguardnonc1test0report &strrep, optguardnonc1test0report &lngrep, const xparams _xparams = alglib::xdefault);
minbcoptguardnonc1test1results function/************************************************************************* Detailed results of the OptGuard integrity check for nonsmoothness test #1 Nonsmoothness (non-C1) test #1 studies individual components of the gradient computed during line search. When precise analytic gradient is provided this test is more powerful than test #0 which works with function values and ignores user-provided gradient. However, test #0 becomes more powerful when numerical differentiation is employed (in such cases test #1 detects higher levels of numerical noise and becomes too conservative). This test also tells specific components of the gradient which violate C1 continuity, which makes it more informative than #0, which just tells that continuity is violated. Two reports are returned: * a "strongest" one, corresponding to line search which had highest value of the nonsmoothness indicator * a "longest" one, corresponding to line search which had more function evaluations, and thus is more detailed In both cases following fields are returned: * positive - is TRUE when test flagged suspicious point; FALSE if test did not notice anything (in the latter cases fields below are empty). * vidx - is an index of the variable in [0,N) with nonsmooth derivative * x0[], d[] - arrays of length N which store initial point and direction for line search (d[] can be normalized, but does not have to) * stp[], g[] - arrays of length CNT which store step lengths and gradient values at these points; g[i] is evaluated in x0+stp[i]*d and contains vidx-th component of the gradient. * stpidxa, stpidxb - we suspect that function violates C1 continuity between steps #stpidxa and #stpidxb (usually we have stpidxb=stpidxa+3, with most likely position of the violation between stpidxa+1 and stpidxa+2. ========================================================================== = SHORTLY SPEAKING: build a 2D plot of (stp,f) and look at it - you will = see where C1 continuity is violated. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: strrep - C1 test #1 "strong" report lngrep - C1 test #1 "long" report -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minbcoptguardnonc1test1results(minbcstate &state, optguardnonc1test1report &strrep, optguardnonc1test1report &lngrep, const xparams _xparams = alglib::xdefault);
minbcoptguardresults function/************************************************************************* Results of OptGuard integrity check, should be called after optimization session is over. === PRIMARY REPORT ======================================================= OptGuard performs several checks which are intended to catch common errors in the implementation of nonlinear function/gradient: * incorrect analytic gradient * discontinuous (non-C0) target functions (constraints) * nonsmooth (non-C1) target functions (constraints) Each of these checks is activated with appropriate function: * minbcoptguardgradient() for gradient verification * minbcoptguardsmoothness() for C0/C1 checks Following flags are set when these errors are suspected: * rep.badgradsuspected, and additionally: * rep.badgradvidx for specific variable (gradient element) suspected * rep.badgradxbase, a point where gradient is tested * rep.badgraduser, user-provided gradient (stored as 2D matrix with single row in order to make report structure compatible with more complex optimizers like MinNLC or MinLM) * rep.badgradnum, reference gradient obtained via numerical differentiation (stored as 2D matrix with single row in order to make report structure compatible with more complex optimizers like MinNLC or MinLM) * rep.nonc0suspected * rep.nonc1suspected === ADDITIONAL REPORTS/LOGS ============================================== Several different tests are performed to catch C0/C1 errors, you can find out specific test signaled error by looking to: * rep.nonc0test0positive, for non-C0 test #0 * rep.nonc1test0positive, for non-C1 test #0 * rep.nonc1test1positive, for non-C1 test #1 Additional information (including line search logs) can be obtained by means of: * minbcoptguardnonc1test0results() * minbcoptguardnonc1test1results() which return detailed error reports, specific points where discontinuities were found, and so on. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: rep - generic OptGuard report; more detailed reports can be retrieved with other functions. NOTE: false negatives (nonsmooth problems are not identified as nonsmooth ones) are possible although unlikely. The reason is that you need to make several evaluations around nonsmoothness in order to accumulate enough information about function curvature. Say, if you start right from the nonsmooth point, optimizer simply won't get enough data to understand what is going wrong before it terminates due to abrupt changes in the derivative. It is also possible that "unlucky" step will move us to the termination too quickly. Our current approach is to have less than 0.1% false negatives in our test examples (measured with multiple restarts from random points), and to have exactly 0% false positives. -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minbcoptguardresults(minbcstate &state, optguardreport &rep, const xparams _xparams = alglib::xdefault);
minbcoptguardsmoothness function/************************************************************************* This function activates/deactivates nonsmoothness monitoring option of the OptGuard integrity checker. Smoothness monitor silently observes solution process and tries to detect ill-posed problems, i.e. ones with: a) discontinuous target function (non-C0) b) nonsmooth target function (non-C1) Smoothness monitoring does NOT interrupt optimization even if it suspects that your problem is nonsmooth. It just sets corresponding flags in the OptGuard report which can be retrieved after optimization is over. Smoothness monitoring is a moderate overhead option which often adds less than 1% to the optimizer running time. Thus, you can use it even for large scale problems. NOTE: OptGuard does NOT guarantee that it will always detect C0/C1 continuity violations. First, minor errors are hard to catch - say, a 0.0001 difference in the model values at two sides of the gap may be due to discontinuity of the model - or simply because the model has changed. Second, C1-violations are especially difficult to detect in a noninvasive way. The optimizer usually performs very short steps near the nonsmoothness, and differentiation usually introduces a lot of numerical noise. It is hard to tell whether some tiny discontinuity in the slope is due to real nonsmoothness or just due to numerical noise alone. Our top priority was to avoid false positives, so in some rare cases minor errors may went unnoticed (however, in most cases they can be spotted with restart from different initial point). INPUT PARAMETERS: state - algorithm state level - monitoring level: * 0 - monitoring is disabled * 1 - noninvasive low-overhead monitoring; function values and/or gradients are recorded, but OptGuard does not try to perform additional evaluations in order to get more information about suspicious locations. === EXPLANATION ========================================================== One major source of headache during optimization is the possibility of the coding errors in the target function/constraints (or their gradients). Such errors most often manifest themselves as discontinuity or nonsmoothness of the target/constraints. Another frequent situation is when you try to optimize something involving lots of min() and max() operations, i.e. nonsmooth target. Although not a coding error, it is nonsmoothness anyway - and smooth optimizers usually stop right after encountering nonsmoothness, well before reaching solution. OptGuard integrity checker helps you to catch such situations: it monitors function values/gradients being passed to the optimizer and tries to errors. Upon discovering suspicious pair of points it raises appropriate flag (and allows you to continue optimization). When optimization is done, you can study OptGuard result. -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minbcoptguardsmoothness(minbcstate &state, const ae_int_t level, const xparams _xparams = alglib::xdefault); void minbcoptguardsmoothness(minbcstate &state, const xparams _xparams = alglib::xdefault);
minbcoptimize function/************************************************************************* This family of functions is used to start iterations of nonlinear optimizer These functions accept following parameters: state - algorithm state func - callback which calculates function (or merit function) value func at given point x grad - callback which calculates function (or merit function) value func and gradient grad at given point x rep - optional callback which is called after each iteration can be NULL ptr - optional pointer which is passed to func/grad/hess/jac/rep can be NULL NOTES: 1. This function has two different implementations: one which uses exact (analytical) user-supplied gradient, and one which uses function value only and numerically differentiates function in order to obtain gradient. Depending on the specific function used to create optimizer object (either MinBCCreate() for analytical gradient or MinBCCreateF() for numerical differentiation) you should choose appropriate variant of MinBCOptimize() - one which accepts function AND gradient or one which accepts function ONLY. Be careful to choose variant of MinBCOptimize() which corresponds to your optimization scheme! Table below lists different combinations of callback (function/gradient) passed to MinBCOptimize() and specific function used to create optimizer. | USER PASSED TO MinBCOptimize() CREATED WITH | function only | function and gradient ------------------------------------------------------------ MinBCCreateF() | works FAILS MinBCCreate() | FAILS works Here "FAIL" denotes inappropriate combinations of optimizer creation function and MinBCOptimize() version. Attemps to use such combination (for example, to create optimizer with MinBCCreateF() and to pass gradient information to MinCGOptimize()) will lead to exception being thrown. Either you did not pass gradient when it WAS needed or you passed gradient when it was NOT needed. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbcoptimize(minbcstate &state, void (*func)(const real_1d_array &x, double &func, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault); void minbcoptimize(minbcstate &state, void (*grad)(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault);
minbcrequesttermination function/************************************************************************* This subroutine submits request for termination of running optimizer. It should be called from user-supplied callback when user decides that it is time to "smoothly" terminate optimization process. As result, optimizer stops at point which was "current accepted" when termination request was submitted and returns error code 8 (successful termination). INPUT PARAMETERS: State - optimizer structure NOTE: after request for termination optimizer may perform several additional calls to user-supplied callbacks. It does NOT guarantee to stop immediately - it just guarantees that these additional calls will be discarded later. NOTE: calling this function on optimizer which is NOT running will have no effect. NOTE: multiple calls to this function are possible. First call is counted, subsequent calls are silently ignored. -- ALGLIB -- Copyright 08.10.2014 by Bochkanov Sergey *************************************************************************/void minbcrequesttermination(minbcstate &state, const xparams _xparams = alglib::xdefault);
minbcrestartfrom function/************************************************************************* This subroutine restarts algorithm from new point. All optimization parameters (including constraints) are left unchanged. This function allows to solve multiple optimization problems (which must have same number of dimensions) without object reallocation penalty. INPUT PARAMETERS: State - structure previously allocated with MinBCCreate call. X - new starting point. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbcrestartfrom(minbcstate &state, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
minbcresults function/************************************************************************* BC results INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: X - array[0..N-1], solution Rep - optimization report. You should check Rep.TerminationType in order to distinguish successful termination from unsuccessful one: * -8 internal integrity control detected infinite or NAN values in function/gradient. Abnormal termination signalled. * -3 inconsistent constraints. * 1 relative function improvement is no more than EpsF. * 2 scaled step is no more than EpsX. * 4 scaled gradient norm is no more than EpsG. * 5 MaxIts steps was taken * 8 terminated by user who called minbcrequesttermination(). X contains point which was "current accepted" when termination request was submitted. More information about fields of this structure can be found in the comments on MinBCReport datatype. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbcresults(const minbcstate &state, real_1d_array &x, minbcreport &rep, const xparams _xparams = alglib::xdefault);
minbcresultsbuf function/************************************************************************* BC results Buffered implementation of MinBCResults() which uses pre-allocated buffer to store X[]. If buffer size is too small, it resizes buffer. It is intended to be used in the inner cycles of performance critical algorithms where array reallocation penalty is too large to be ignored. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbcresultsbuf(const minbcstate &state, real_1d_array &x, minbcreport &rep, const xparams _xparams = alglib::xdefault);
minbcsetbc function/************************************************************************* This function sets boundary constraints for BC optimizer. Boundary constraints are inactive by default (after initial creation). They are preserved after algorithm restart with MinBCRestartFrom(). INPUT PARAMETERS: State - structure stores algorithm state BndL - lower bounds, array[N]. If some (all) variables are unbounded, you may specify very small number or -INF. BndU - upper bounds, array[N]. If some (all) variables are unbounded, you may specify very large number or +INF. NOTE 1: it is possible to specify BndL[i]=BndU[i]. In this case I-th variable will be "frozen" at X[i]=BndL[i]=BndU[i]. NOTE 2: this solver has following useful properties: * bound constraints are always satisfied exactly * function is evaluated only INSIDE area specified by bound constraints, even when numerical differentiation is used (algorithm adjusts nodes according to boundary constraints) -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbcsetbc(minbcstate &state, const real_1d_array &bndl, const real_1d_array &bndu, const xparams _xparams = alglib::xdefault);
minbcsetcond function/************************************************************************* This function sets stopping conditions for the optimizer. INPUT PARAMETERS: State - structure which stores algorithm state EpsG - >=0 The subroutine finishes its work if the condition |v|<EpsG is satisfied, where: * |.| means Euclidian norm * v - scaled gradient vector, v[i]=g[i]*s[i] * g - gradient * s - scaling coefficients set by MinBCSetScale() EpsF - >=0 The subroutine finishes its work if on k+1-th iteration the condition |F(k+1)-F(k)|<=EpsF*max{|F(k)|,|F(k+1)|,1} is satisfied. EpsX - >=0 The subroutine finishes its work if on k+1-th iteration the condition |v|<=EpsX is fulfilled, where: * |.| means Euclidian norm * v - scaled step vector, v[i]=dx[i]/s[i] * dx - step vector, dx=X(k+1)-X(k) * s - scaling coefficients set by MinBCSetScale() MaxIts - maximum number of iterations. If MaxIts=0, the number of iterations is unlimited. Passing EpsG=0, EpsF=0 and EpsX=0 and MaxIts=0 (simultaneously) will lead to automatic stopping criterion selection. NOTE: when SetCond() called with non-zero MaxIts, BC solver may perform slightly more than MaxIts iterations. I.e., MaxIts sets non-strict limit on iterations count. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbcsetcond(minbcstate &state, const double epsg, const double epsf, const double epsx, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
minbcsetprecdefault function/************************************************************************* Modification of the preconditioner: preconditioning is turned off. INPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minbcsetprecdefault(minbcstate &state, const xparams _xparams = alglib::xdefault);
minbcsetprecdiag function/************************************************************************* Modification of the preconditioner: diagonal of approximate Hessian is used. INPUT PARAMETERS: State - structure which stores algorithm state D - diagonal of the approximate Hessian, array[0..N-1], (if larger, only leading N elements are used). NOTE 1: D[i] should be positive. Exception will be thrown otherwise. NOTE 2: you should pass diagonal of approximate Hessian - NOT ITS INVERSE. -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minbcsetprecdiag(minbcstate &state, const real_1d_array &d, const xparams _xparams = alglib::xdefault);
minbcsetprecscale function/************************************************************************* Modification of the preconditioner: scale-based diagonal preconditioning. This preconditioning mode can be useful when you don't have approximate diagonal of Hessian, but you know that your variables are badly scaled (for example, one variable is in [1,10], and another in [1000,100000]), and most part of the ill-conditioning comes from different scales of vars. In this case simple scale-based preconditioner, with H[i] = 1/(s[i]^2), can greatly improve convergence. IMPRTANT: you should set scale of your variables with MinBCSetScale() call (before or after MinBCSetPrecScale() call). Without knowledge of the scale of your variables scale-based preconditioner will be just unit matrix. INPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minbcsetprecscale(minbcstate &state, const xparams _xparams = alglib::xdefault);
minbcsetscale function/************************************************************************* This function sets scaling coefficients for BC optimizer. ALGLIB optimizers use scaling matrices to test stopping conditions (step size and gradient are scaled before comparison with tolerances). Scale of the I-th variable is a translation invariant measure of: a) "how large" the variable is b) how large the step should be to make significant changes in the function Scaling is also used by finite difference variant of the optimizer - step along I-th axis is equal to DiffStep*S[I]. In most optimizers (and in the BC too) scaling is NOT a form of preconditioning. It just affects stopping conditions. You should set preconditioner by separate call to one of the MinBCSetPrec...() functions. There is a special preconditioning mode, however, which uses scaling coefficients to form diagonal preconditioning matrix. You can turn this mode on, if you want. But you should understand that scaling is not the same thing as preconditioning - these are two different, although related forms of tuning solver. INPUT PARAMETERS: State - structure stores algorithm state S - array[N], non-zero scaling coefficients S[i] may be negative, sign doesn't matter. -- ALGLIB -- Copyright 14.01.2011 by Bochkanov Sergey *************************************************************************/void minbcsetscale(minbcstate &state, const real_1d_array &s, const xparams _xparams = alglib::xdefault);
minbcsetstpmax function/************************************************************************* This function sets maximum step length INPUT PARAMETERS: State - structure which stores algorithm state StpMax - maximum step length, >=0. Set StpMax to 0.0, if you don't want to limit step length. Use this subroutine when you optimize target function which contains exp() or other fast growing functions, and optimization algorithm makes too large steps which lead to overflow. This function allows us to reject steps that are too large (and therefore expose us to the possible overflow) without actually calculating function value at the x+stp*d. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minbcsetstpmax(minbcstate &state, const double stpmax, const xparams _xparams = alglib::xdefault);
minbcsetxrep function/************************************************************************* This function turns on/off reporting. INPUT PARAMETERS: State - structure which stores algorithm state NeedXRep- whether iteration reports are needed or not If NeedXRep is True, algorithm will call rep() callback function if it is provided to MinBCOptimize(). -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbcsetxrep(minbcstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_grad(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
// and its derivatives df/d0 and df/dx1
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
grad[0] = 400*pow(x[0]+3,3);
grad[1] = 4*pow(x[1]-3,3);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of
//
// f(x,y) = 100*(x+3)^4+(y-3)^4
//
// subject to box constraints
//
// -1<=x<=+1, -1<=y<=+1
//
// using MinBC optimizer with:
// * initial point x=[0,0]
// * unit scale being set for all variables (see minbcsetscale for more info)
// * stopping criteria set to "terminate after short enough step"
// * OptGuard integrity check being used to check problem statement
// for some common errors like nonsmoothness or bad analytic gradient
//
// First, we create optimizer object and tune its properties:
// * set box constraints
// * set variable scales
// * set stopping criteria
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
real_1d_array bndl = "[-1,-1]";
real_1d_array bndu = "[+1,+1]";
minbcstate state;
double epsg = 0;
double epsf = 0;
double epsx = 0.000001;
ae_int_t maxits = 0;
minbccreate(x, state);
minbcsetbc(state, bndl, bndu);
minbcsetscale(state, s);
minbcsetcond(state, epsg, epsf, epsx, maxits);
//
// Then we activate OptGuard integrity checking.
//
// OptGuard monitor helps to catch common coding and problem statement
// issues, like:
// * discontinuity of the target function (C0 continuity violation)
// * nonsmoothness of the target function (C1 continuity violation)
// * erroneous analytic gradient, i.e. one inconsistent with actual
// change in the target/constraints
//
// OptGuard is essential for early prototyping stages because such
// problems often result in premature termination of the optimizer
// which is really hard to distinguish from the correct termination.
//
// IMPORTANT: GRADIENT VERIFICATION IS PERFORMED BY MEANS OF NUMERICAL
// DIFFERENTIATION. DO NOT USE IT IN PRODUCTION CODE!!!!!!!
//
// Other OptGuard checks add moderate overhead, but anyway
// it is better to turn them off when they are not needed.
//
minbcoptguardsmoothness(state);
minbcoptguardgradient(state, 0.001);
//
// Optimize and evaluate results
//
minbcreport rep;
alglib::minbcoptimize(state, function1_grad);
minbcresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-1,1]
//
// Check that OptGuard did not report errors
//
// NOTE: want to test OptGuard? Try breaking the gradient - say, add
// 1.0 to some of its components.
//
optguardreport ogrep;
minbcoptguardresults(state, ogrep);
printf("%s\n", ogrep.badgradsuspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc0suspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc1suspected ? "true" : "false"); // EXPECTED: false
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_func(const real_1d_array &x, double &func, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of
//
// f(x,y) = 100*(x+3)^4+(y-3)^4
//
// subject to box constraints
//
// -1<=x<=+1, -1<=y<=+1
//
// using MinBC optimizer with:
// * numerical differentiation being used
// * initial point x=[0,0]
// * unit scale being set for all variables (see minbcsetscale for more info)
// * stopping criteria set to "terminate after short enough step"
// * OptGuard integrity check being used to check problem statement
// for some common errors like nonsmoothness or bad analytic gradient
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
real_1d_array bndl = "[-1,-1]";
real_1d_array bndu = "[+1,+1]";
minbcstate state;
double epsg = 0;
double epsf = 0;
double epsx = 0.000001;
ae_int_t maxits = 0;
double diffstep = 1.0e-6;
//
// Now we are ready to actually optimize something:
// * first we create optimizer
// * we add boundary constraints
// * we tune stopping conditions
// * and, finally, optimize and obtain results...
//
minbccreatef(x, diffstep, state);
minbcsetbc(state, bndl, bndu);
minbcsetscale(state, s);
minbcsetcond(state, epsg, epsf, epsx, maxits);
//
// Then we activate OptGuard integrity checking.
//
// Numerical differentiation always produces "correct" gradient
// (with some truncation error, but unbiased). Thus, we just have
// to check smoothness properties of the target: C0 and C1 continuity.
//
// Sometimes user accidentally tries to solve nonsmooth problems
// with smooth optimizer. OptGuard helps to detect such situations
// early, at the prototyping stage.
//
minbcoptguardsmoothness(state);
//
// Optimize and evaluate results
//
minbcreport rep;
alglib::minbcoptimize(state, function1_func);
minbcresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-1,1]
//
// Check that OptGuard did not report errors
//
// Want to challenge OptGuard? Try to make your problem
// nonsmooth by replacing 100*(x+3)^4 by 100*|x+3| and
// re-run optimizer.
//
optguardreport ogrep;
minbcoptguardresults(state, ogrep);
printf("%s\n", ogrep.nonc0suspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc1suspected ? "true" : "false"); // EXPECTED: false
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
minbleic subpackage| minbleic_d_1 | Nonlinear optimization with bound constraints | |
| minbleic_d_2 | Nonlinear optimization with linear inequality constraints | |
| minbleic_numdiff | Nonlinear optimization with bound constraints and numerical differentiation |
minbleicreport class/************************************************************************* This structure stores optimization report: * IterationsCount number of iterations * NFEV number of gradient evaluations * TerminationType termination type (see below) TERMINATION CODES TerminationType field contains completion code, which can be: -8 internal integrity control detected infinite or NAN values in function/gradient. Abnormal termination signalled. -3 inconsistent constraints. Feasible point is either nonexistent or too hard to find. Try to restart optimizer with better initial approximation 1 relative function improvement is no more than EpsF. 2 relative step is no more than EpsX. 4 gradient norm is no more than EpsG 5 MaxIts steps was taken 7 stopping conditions are too stringent, further improvement is impossible, X contains best point found so far. 8 terminated by user who called minbleicrequesttermination(). X contains point which was "current accepted" when termination request was submitted. ADDITIONAL FIELDS There are additional fields which can be used for debugging: * DebugEqErr error in the equality constraints (2-norm) * DebugFS f, calculated at projection of initial point to the feasible set * DebugFF f, calculated at the final point * DebugDX |X_start-X_final| *************************************************************************/class minbleicreport { public: minbleicreport(); minbleicreport(const minbleicreport &rhs); minbleicreport& operator=(const minbleicreport &rhs); virtual ~minbleicreport(); ae_int_t iterationscount; ae_int_t nfev; ae_int_t varidx; ae_int_t terminationtype; double debugeqerr; double debugfs; double debugff; double debugdx; ae_int_t debugfeasqpits; ae_int_t debugfeasgpaits; ae_int_t inneriterationscount; ae_int_t outeriterationscount; };
minbleicstate class/************************************************************************* This object stores nonlinear optimizer state. You should use functions provided by MinBLEIC subpackage to work with this object *************************************************************************/class minbleicstate { public: minbleicstate(); minbleicstate(const minbleicstate &rhs); minbleicstate& operator=(const minbleicstate &rhs); virtual ~minbleicstate(); };
minbleiccreate function/************************************************************************* BOUND CONSTRAINED OPTIMIZATION WITH ADDITIONAL LINEAR EQUALITY AND INEQUALITY CONSTRAINTS DESCRIPTION: The subroutine minimizes function F(x) of N arguments subject to any combination of: * bound constraints * linear inequality constraints * linear equality constraints REQUIREMENTS: * user must provide function value and gradient * starting point X0 must be feasible or not too far away from the feasible set * grad(f) must be Lipschitz continuous on a level set: L = { x : f(x)<=f(x0) } * function must be defined everywhere on the feasible set F USAGE: Constrained optimization if far more complex than the unconstrained one. Here we give very brief outline of the BLEIC optimizer. We strongly recommend you to read examples in the ALGLIB Reference Manual and to read ALGLIB User Guide on optimization, which is available at http://www.alglib.net/optimization/ 1. User initializes algorithm state with MinBLEICCreate() call 2. USer adds boundary and/or linear constraints by calling MinBLEICSetBC() and MinBLEICSetLC() functions. 3. User sets stopping conditions with MinBLEICSetCond(). 4. User calls MinBLEICOptimize() function which takes algorithm state and pointer (delegate, etc.) to callback function which calculates F/G. 5. User calls MinBLEICResults() to get solution 6. Optionally user may call MinBLEICRestartFrom() to solve another problem with same N but another starting point. MinBLEICRestartFrom() allows to reuse already initialized structure. NOTE: if you have box-only constraints (no general linear constraints), then MinBC optimizer can be better option. It uses special, faster constraint activation method, which performs better on problems with multiple constraints active at the solution. On small-scale problems performance of MinBC is similar to that of MinBLEIC, but on large-scale ones (hundreds and thousands of active constraints) it can be several times faster than MinBLEIC. INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of X are used * if not given, automatically determined from size ofX X - starting point, array[N]: * it is better to set X to a feasible point * but X can be infeasible, in which case algorithm will try to find feasible point first, using X as initial approximation. OUTPUT PARAMETERS: State - structure stores algorithm state -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleiccreate(const ae_int_t n, const real_1d_array &x, minbleicstate &state, const xparams _xparams = alglib::xdefault); void minbleiccreate(const real_1d_array &x, minbleicstate &state, const xparams _xparams = alglib::xdefault);
minbleiccreatef function/************************************************************************* The subroutine is finite difference variant of MinBLEICCreate(). It uses finite differences in order to differentiate target function. Description below contains information which is specific to this function only. We recommend to read comments on MinBLEICCreate() in order to get more information about creation of BLEIC optimizer. INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of X are used * if not given, automatically determined from size of X X - starting point, array[0..N-1]. DiffStep- differentiation step, >0 OUTPUT PARAMETERS: State - structure which stores algorithm state NOTES: 1. algorithm uses 4-point central formula for differentiation. 2. differentiation step along I-th axis is equal to DiffStep*S[I] where S[] is scaling vector which can be set by MinBLEICSetScale() call. 3. we recommend you to use moderate values of differentiation step. Too large step will result in too large truncation errors, while too small step will result in too large numerical errors. 1.0E-6 can be good value to start with. 4. Numerical differentiation is very inefficient - one gradient calculation needs 4*N function evaluations. This function will work for any N - either small (1...10), moderate (10...100) or large (100...). However, performance penalty will be too severe for any N's except for small ones. We should also say that code which relies on numerical differentiation is less robust and precise. CG needs exact gradient values. Imprecise gradient may slow down convergence, especially on highly nonlinear problems. Thus we recommend to use this function for fast prototyping on small- dimensional problems only, and to implement analytical gradient as soon as possible. -- ALGLIB -- Copyright 16.05.2011 by Bochkanov Sergey *************************************************************************/void minbleiccreatef(const ae_int_t n, const real_1d_array &x, const double diffstep, minbleicstate &state, const xparams _xparams = alglib::xdefault); void minbleiccreatef(const real_1d_array &x, const double diffstep, minbleicstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
minbleiciteration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool minbleiciteration(minbleicstate &state, const xparams _xparams = alglib::xdefault);
minbleicoptguardgradient function/************************************************************************* This function activates/deactivates verification of the user-supplied analytic gradient. Upon activation of this option OptGuard integrity checker performs numerical differentiation of your target function at the initial point (note: future versions may also perform check at the final point) and compares numerical gradient with analytic one provided by you. If difference is too large, an error flag is set and optimization session continues. After optimization session is over, you can retrieve the report which stores both gradients and specific components highlighted as suspicious by the OptGuard. The primary OptGuard report can be retrieved with minbleicoptguardresults(). IMPORTANT: gradient check is a high-overhead option which will cost you about 3*N additional function evaluations. In many cases it may cost as much as the rest of the optimization session. YOU SHOULD NOT USE IT IN THE PRODUCTION CODE UNLESS YOU WANT TO CHECK DERIVATIVES PROVIDED BY SOME THIRD PARTY. NOTE: unlike previous incarnation of the gradient checking code, OptGuard does NOT interrupt optimization even if it discovers bad gradient. INPUT PARAMETERS: State - structure used to store algorithm state TestStep - verification step used for numerical differentiation: * TestStep=0 turns verification off * TestStep>0 activates verification You should carefully choose TestStep. Value which is too large (so large that function behavior is non- cubic at this scale) will lead to false alarms. Too short step will result in rounding errors dominating numerical derivative. You may use different step for different parameters by means of setting scale with minbleicsetscale(). === EXPLANATION ========================================================== In order to verify gradient algorithm performs following steps: * two trial steps are made to X[i]-TestStep*S[i] and X[i]+TestStep*S[i], where X[i] is i-th component of the initial point and S[i] is a scale of i-th parameter * F(X) is evaluated at these trial points * we perform one more evaluation in the middle point of the interval * we build cubic model using function values and derivatives at trial points and we compare its prediction with actual value in the middle point -- ALGLIB -- Copyright 15.06.2014 by Bochkanov Sergey *************************************************************************/void minbleicoptguardgradient(minbleicstate &state, const double teststep, const xparams _xparams = alglib::xdefault);
minbleicoptguardnonc1test0results function/************************************************************************* Detailed results of the OptGuard integrity check for nonsmoothness test #0 Nonsmoothness (non-C1) test #0 studies function values (not gradient!) obtained during line searches and monitors behavior of the directional derivative estimate. This test is less powerful than test #1, but it does not depend on the gradient values and thus it is more robust against artifacts introduced by numerical differentiation. Two reports are returned: * a "strongest" one, corresponding to line search which had highest value of the nonsmoothness indicator * a "longest" one, corresponding to line search which had more function evaluations, and thus is more detailed In both cases following fields are returned: * positive - is TRUE when test flagged suspicious point; FALSE if test did not notice anything (in the latter cases fields below are empty). * x0[], d[] - arrays of length N which store initial point and direction for line search (d[] can be normalized, but does not have to) * stp[], f[] - arrays of length CNT which store step lengths and function values at these points; f[i] is evaluated in x0+stp[i]*d. * stpidxa, stpidxb - we suspect that function violates C1 continuity between steps #stpidxa and #stpidxb (usually we have stpidxb=stpidxa+3, with most likely position of the violation between stpidxa+1 and stpidxa+2. ========================================================================== = SHORTLY SPEAKING: build a 2D plot of (stp,f) and look at it - you will = see where C1 continuity is violated. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: strrep - C1 test #0 "strong" report lngrep - C1 test #0 "long" report -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minbleicoptguardnonc1test0results(const minbleicstate &state, optguardnonc1test0report &strrep, optguardnonc1test0report &lngrep, const xparams _xparams = alglib::xdefault);
minbleicoptguardnonc1test1results function/************************************************************************* Detailed results of the OptGuard integrity check for nonsmoothness test #1 Nonsmoothness (non-C1) test #1 studies individual components of the gradient computed during line search. When precise analytic gradient is provided this test is more powerful than test #0 which works with function values and ignores user-provided gradient. However, test #0 becomes more powerful when numerical differentiation is employed (in such cases test #1 detects higher levels of numerical noise and becomes too conservative). This test also tells specific components of the gradient which violate C1 continuity, which makes it more informative than #0, which just tells that continuity is violated. Two reports are returned: * a "strongest" one, corresponding to line search which had highest value of the nonsmoothness indicator * a "longest" one, corresponding to line search which had more function evaluations, and thus is more detailed In both cases following fields are returned: * positive - is TRUE when test flagged suspicious point; FALSE if test did not notice anything (in the latter cases fields below are empty). * vidx - is an index of the variable in [0,N) with nonsmooth derivative * x0[], d[] - arrays of length N which store initial point and direction for line search (d[] can be normalized, but does not have to) * stp[], g[] - arrays of length CNT which store step lengths and gradient values at these points; g[i] is evaluated in x0+stp[i]*d and contains vidx-th component of the gradient. * stpidxa, stpidxb - we suspect that function violates C1 continuity between steps #stpidxa and #stpidxb (usually we have stpidxb=stpidxa+3, with most likely position of the violation between stpidxa+1 and stpidxa+2. ========================================================================== = SHORTLY SPEAKING: build a 2D plot of (stp,f) and look at it - you will = see where C1 continuity is violated. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: strrep - C1 test #1 "strong" report lngrep - C1 test #1 "long" report -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minbleicoptguardnonc1test1results(minbleicstate &state, optguardnonc1test1report &strrep, optguardnonc1test1report &lngrep, const xparams _xparams = alglib::xdefault);
minbleicoptguardresults function/************************************************************************* Results of OptGuard integrity check, should be called after optimization session is over. === PRIMARY REPORT ======================================================= OptGuard performs several checks which are intended to catch common errors in the implementation of nonlinear function/gradient: * incorrect analytic gradient * discontinuous (non-C0) target functions (constraints) * nonsmooth (non-C1) target functions (constraints) Each of these checks is activated with appropriate function: * minbleicoptguardgradient() for gradient verification * minbleicoptguardsmoothness() for C0/C1 checks Following flags are set when these errors are suspected: * rep.badgradsuspected, and additionally: * rep.badgradvidx for specific variable (gradient element) suspected * rep.badgradxbase, a point where gradient is tested * rep.badgraduser, user-provided gradient (stored as 2D matrix with single row in order to make report structure compatible with more complex optimizers like MinNLC or MinLM) * rep.badgradnum, reference gradient obtained via numerical differentiation (stored as 2D matrix with single row in order to make report structure compatible with more complex optimizers like MinNLC or MinLM) * rep.nonc0suspected * rep.nonc1suspected === ADDITIONAL REPORTS/LOGS ============================================== Several different tests are performed to catch C0/C1 errors, you can find out specific test signaled error by looking to: * rep.nonc0test0positive, for non-C0 test #0 * rep.nonc1test0positive, for non-C1 test #0 * rep.nonc1test1positive, for non-C1 test #1 Additional information (including line search logs) can be obtained by means of: * minbleicoptguardnonc1test0results() * minbleicoptguardnonc1test1results() which return detailed error reports, specific points where discontinuities were found, and so on. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: rep - generic OptGuard report; more detailed reports can be retrieved with other functions. NOTE: false negatives (nonsmooth problems are not identified as nonsmooth ones) are possible although unlikely. The reason is that you need to make several evaluations around nonsmoothness in order to accumulate enough information about function curvature. Say, if you start right from the nonsmooth point, optimizer simply won't get enough data to understand what is going wrong before it terminates due to abrupt changes in the derivative. It is also possible that "unlucky" step will move us to the termination too quickly. Our current approach is to have less than 0.1% false negatives in our test examples (measured with multiple restarts from random points), and to have exactly 0% false positives. -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minbleicoptguardresults(minbleicstate &state, optguardreport &rep, const xparams _xparams = alglib::xdefault);
minbleicoptguardsmoothness function/************************************************************************* This function activates/deactivates nonsmoothness monitoring option of the OptGuard integrity checker. Smoothness monitor silently observes solution process and tries to detect ill-posed problems, i.e. ones with: a) discontinuous target function (non-C0) b) nonsmooth target function (non-C1) Smoothness monitoring does NOT interrupt optimization even if it suspects that your problem is nonsmooth. It just sets corresponding flags in the OptGuard report which can be retrieved after optimization is over. Smoothness monitoring is a moderate overhead option which often adds less than 1% to the optimizer running time. Thus, you can use it even for large scale problems. NOTE: OptGuard does NOT guarantee that it will always detect C0/C1 continuity violations. First, minor errors are hard to catch - say, a 0.0001 difference in the model values at two sides of the gap may be due to discontinuity of the model - or simply because the model has changed. Second, C1-violations are especially difficult to detect in a noninvasive way. The optimizer usually performs very short steps near the nonsmoothness, and differentiation usually introduces a lot of numerical noise. It is hard to tell whether some tiny discontinuity in the slope is due to real nonsmoothness or just due to numerical noise alone. Our top priority was to avoid false positives, so in some rare cases minor errors may went unnoticed (however, in most cases they can be spotted with restart from different initial point). INPUT PARAMETERS: state - algorithm state level - monitoring level: * 0 - monitoring is disabled * 1 - noninvasive low-overhead monitoring; function values and/or gradients are recorded, but OptGuard does not try to perform additional evaluations in order to get more information about suspicious locations. === EXPLANATION ========================================================== One major source of headache during optimization is the possibility of the coding errors in the target function/constraints (or their gradients). Such errors most often manifest themselves as discontinuity or nonsmoothness of the target/constraints. Another frequent situation is when you try to optimize something involving lots of min() and max() operations, i.e. nonsmooth target. Although not a coding error, it is nonsmoothness anyway - and smooth optimizers usually stop right after encountering nonsmoothness, well before reaching solution. OptGuard integrity checker helps you to catch such situations: it monitors function values/gradients being passed to the optimizer and tries to errors. Upon discovering suspicious pair of points it raises appropriate flag (and allows you to continue optimization). When optimization is done, you can study OptGuard result. -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minbleicoptguardsmoothness(minbleicstate &state, const ae_int_t level, const xparams _xparams = alglib::xdefault); void minbleicoptguardsmoothness(minbleicstate &state, const xparams _xparams = alglib::xdefault);
minbleicoptimize function/************************************************************************* This family of functions is used to start iterations of nonlinear optimizer These functions accept following parameters: state - algorithm state func - callback which calculates function (or merit function) value func at given point x grad - callback which calculates function (or merit function) value func and gradient grad at given point x rep - optional callback which is called after each iteration can be NULL ptr - optional pointer which is passed to func/grad/hess/jac/rep can be NULL NOTES: 1. This function has two different implementations: one which uses exact (analytical) user-supplied gradient, and one which uses function value only and numerically differentiates function in order to obtain gradient. Depending on the specific function used to create optimizer object (either MinBLEICCreate() for analytical gradient or MinBLEICCreateF() for numerical differentiation) you should choose appropriate variant of MinBLEICOptimize() - one which accepts function AND gradient or one which accepts function ONLY. Be careful to choose variant of MinBLEICOptimize() which corresponds to your optimization scheme! Table below lists different combinations of callback (function/gradient) passed to MinBLEICOptimize() and specific function used to create optimizer. | USER PASSED TO MinBLEICOptimize() CREATED WITH | function only | function and gradient ------------------------------------------------------------ MinBLEICCreateF() | work FAIL MinBLEICCreate() | FAIL work Here "FAIL" denotes inappropriate combinations of optimizer creation function and MinBLEICOptimize() version. Attemps to use such combination (for example, to create optimizer with MinBLEICCreateF() and to pass gradient information to MinBLEICOptimize()) will lead to exception being thrown. Either you did not pass gradient when it WAS needed or you passed gradient when it was NOT needed. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleicoptimize(minbleicstate &state, void (*func)(const real_1d_array &x, double &func, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault); void minbleicoptimize(minbleicstate &state, void (*grad)(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault);
minbleicrequesttermination function/************************************************************************* This subroutine submits request for termination of running optimizer. It should be called from user-supplied callback when user decides that it is time to "smoothly" terminate optimization process. As result, optimizer stops at point which was "current accepted" when termination request was submitted and returns error code 8 (successful termination). INPUT PARAMETERS: State - optimizer structure NOTE: after request for termination optimizer may perform several additional calls to user-supplied callbacks. It does NOT guarantee to stop immediately - it just guarantees that these additional calls will be discarded later. NOTE: calling this function on optimizer which is NOT running will have no effect. NOTE: multiple calls to this function are possible. First call is counted, subsequent calls are silently ignored. -- ALGLIB -- Copyright 08.10.2014 by Bochkanov Sergey *************************************************************************/void minbleicrequesttermination(minbleicstate &state, const xparams _xparams = alglib::xdefault);
minbleicrestartfrom function/************************************************************************* This subroutine restarts algorithm from new point. All optimization parameters (including constraints) are left unchanged. This function allows to solve multiple optimization problems (which must have same number of dimensions) without object reallocation penalty. INPUT PARAMETERS: State - structure previously allocated with MinBLEICCreate call. X - new starting point. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleicrestartfrom(minbleicstate &state, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
minbleicresults function/************************************************************************* BLEIC results INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: X - array[0..N-1], solution Rep - optimization report. You should check Rep.TerminationType in order to distinguish successful termination from unsuccessful one: * -8 internal integrity control detected infinite or NAN values in function/gradient. Abnormal termination signalled. * -3 inconsistent constraints. Feasible point is either nonexistent or too hard to find. Try to restart optimizer with better initial approximation * 1 relative function improvement is no more than EpsF. * 2 scaled step is no more than EpsX. * 4 scaled gradient norm is no more than EpsG. * 5 MaxIts steps was taken * 8 terminated by user who called minbleicrequesttermination(). X contains point which was "current accepted" when termination request was submitted. More information about fields of this structure can be found in the comments on MinBLEICReport datatype. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleicresults(const minbleicstate &state, real_1d_array &x, minbleicreport &rep, const xparams _xparams = alglib::xdefault);
minbleicresultsbuf function/************************************************************************* BLEIC results Buffered implementation of MinBLEICResults() which uses pre-allocated buffer to store X[]. If buffer size is too small, it resizes buffer. It is intended to be used in the inner cycles of performance critical algorithms where array reallocation penalty is too large to be ignored. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleicresultsbuf(const minbleicstate &state, real_1d_array &x, minbleicreport &rep, const xparams _xparams = alglib::xdefault);
minbleicsetbc function/************************************************************************* This function sets boundary constraints for BLEIC optimizer. Boundary constraints are inactive by default (after initial creation). They are preserved after algorithm restart with MinBLEICRestartFrom(). NOTE: if you have box-only constraints (no general linear constraints), then MinBC optimizer can be better option. It uses special, faster constraint activation method, which performs better on problems with multiple constraints active at the solution. On small-scale problems performance of MinBC is similar to that of MinBLEIC, but on large-scale ones (hundreds and thousands of active constraints) it can be several times faster than MinBLEIC. INPUT PARAMETERS: State - structure stores algorithm state BndL - lower bounds, array[N]. If some (all) variables are unbounded, you may specify very small number or -INF. BndU - upper bounds, array[N]. If some (all) variables are unbounded, you may specify very large number or +INF. NOTE 1: it is possible to specify BndL[i]=BndU[i]. In this case I-th variable will be "frozen" at X[i]=BndL[i]=BndU[i]. NOTE 2: this solver has following useful properties: * bound constraints are always satisfied exactly * function is evaluated only INSIDE area specified by bound constraints, even when numerical differentiation is used (algorithm adjusts nodes according to boundary constraints) -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleicsetbc(minbleicstate &state, const real_1d_array &bndl, const real_1d_array &bndu, const xparams _xparams = alglib::xdefault);
minbleicsetcond function/************************************************************************* This function sets stopping conditions for the optimizer. INPUT PARAMETERS: State - structure which stores algorithm state EpsG - >=0 The subroutine finishes its work if the condition |v|<EpsG is satisfied, where: * |.| means Euclidian norm * v - scaled gradient vector, v[i]=g[i]*s[i] * g - gradient * s - scaling coefficients set by MinBLEICSetScale() EpsF - >=0 The subroutine finishes its work if on k+1-th iteration the condition |F(k+1)-F(k)|<=EpsF*max{|F(k)|,|F(k+1)|,1} is satisfied. EpsX - >=0 The subroutine finishes its work if on k+1-th iteration the condition |v|<=EpsX is fulfilled, where: * |.| means Euclidian norm * v - scaled step vector, v[i]=dx[i]/s[i] * dx - step vector, dx=X(k+1)-X(k) * s - scaling coefficients set by MinBLEICSetScale() MaxIts - maximum number of iterations. If MaxIts=0, the number of iterations is unlimited. Passing EpsG=0, EpsF=0 and EpsX=0 and MaxIts=0 (simultaneously) will lead to automatic stopping criterion selection. NOTE: when SetCond() called with non-zero MaxIts, BLEIC solver may perform slightly more than MaxIts iterations. I.e., MaxIts sets non-strict limit on iterations count. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleicsetcond(minbleicstate &state, const double epsg, const double epsf, const double epsx, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
minbleicsetlc function/************************************************************************* This function sets linear constraints for BLEIC optimizer. Linear constraints are inactive by default (after initial creation). They are preserved after algorithm restart with MinBLEICRestartFrom(). INPUT PARAMETERS: State - structure previously allocated with MinBLEICCreate call. C - linear constraints, array[K,N+1]. Each row of C represents one constraint, either equality or inequality (see below): * first N elements correspond to coefficients, * last element corresponds to the right part. All elements of C (including right part) must be finite. CT - type of constraints, array[K]: * if CT[i]>0, then I-th constraint is C[i,*]*x >= C[i,n] * if CT[i]=0, then I-th constraint is C[i,*]*x = C[i,n] * if CT[i]<0, then I-th constraint is C[i,*]*x <= C[i,n] K - number of equality/inequality constraints, K>=0: * if given, only leading K elements of C/CT are used * if not given, automatically determined from sizes of C/CT NOTE 1: linear (non-bound) constraints are satisfied only approximately: * there always exists some minor violation (about Epsilon in magnitude) due to rounding errors * numerical differentiation, if used, may lead to function evaluations outside of the feasible area, because algorithm does NOT change numerical differentiation formula according to linear constraints. If you want constraints to be satisfied exactly, try to reformulate your problem in such manner that all constraints will become boundary ones (this kind of constraints is always satisfied exactly, both in the final solution and in all intermediate points). -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleicsetlc(minbleicstate &state, const real_2d_array &c, const integer_1d_array &ct, const ae_int_t k, const xparams _xparams = alglib::xdefault); void minbleicsetlc(minbleicstate &state, const real_2d_array &c, const integer_1d_array &ct, const xparams _xparams = alglib::xdefault);
Examples: [1]
minbleicsetprecdefault function/************************************************************************* Modification of the preconditioner: preconditioning is turned off. INPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minbleicsetprecdefault(minbleicstate &state, const xparams _xparams = alglib::xdefault);
minbleicsetprecdiag function/************************************************************************* Modification of the preconditioner: diagonal of approximate Hessian is used. INPUT PARAMETERS: State - structure which stores algorithm state D - diagonal of the approximate Hessian, array[0..N-1], (if larger, only leading N elements are used). NOTE 1: D[i] should be positive. Exception will be thrown otherwise. NOTE 2: you should pass diagonal of approximate Hessian - NOT ITS INVERSE. -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minbleicsetprecdiag(minbleicstate &state, const real_1d_array &d, const xparams _xparams = alglib::xdefault);
minbleicsetprecscale function/************************************************************************* Modification of the preconditioner: scale-based diagonal preconditioning. This preconditioning mode can be useful when you don't have approximate diagonal of Hessian, but you know that your variables are badly scaled (for example, one variable is in [1,10], and another in [1000,100000]), and most part of the ill-conditioning comes from different scales of vars. In this case simple scale-based preconditioner, with H[i] = 1/(s[i]^2), can greatly improve convergence. IMPRTANT: you should set scale of your variables with MinBLEICSetScale() call (before or after MinBLEICSetPrecScale() call). Without knowledge of the scale of your variables scale-based preconditioner will be just unit matrix. INPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minbleicsetprecscale(minbleicstate &state, const xparams _xparams = alglib::xdefault);
minbleicsetscale function/************************************************************************* This function sets scaling coefficients for BLEIC optimizer. ALGLIB optimizers use scaling matrices to test stopping conditions (step size and gradient are scaled before comparison with tolerances). Scale of the I-th variable is a translation invariant measure of: a) "how large" the variable is b) how large the step should be to make significant changes in the function Scaling is also used by finite difference variant of the optimizer - step along I-th axis is equal to DiffStep*S[I]. In most optimizers (and in the BLEIC too) scaling is NOT a form of preconditioning. It just affects stopping conditions. You should set preconditioner by separate call to one of the MinBLEICSetPrec...() functions. There is a special preconditioning mode, however, which uses scaling coefficients to form diagonal preconditioning matrix. You can turn this mode on, if you want. But you should understand that scaling is not the same thing as preconditioning - these are two different, although related forms of tuning solver. INPUT PARAMETERS: State - structure stores algorithm state S - array[N], non-zero scaling coefficients S[i] may be negative, sign doesn't matter. -- ALGLIB -- Copyright 14.01.2011 by Bochkanov Sergey *************************************************************************/void minbleicsetscale(minbleicstate &state, const real_1d_array &s, const xparams _xparams = alglib::xdefault);
minbleicsetstpmax function/************************************************************************* This function sets maximum step length IMPORTANT: this feature is hard to combine with preconditioning. You can't set upper limit on step length, when you solve optimization problem with linear (non-boundary) constraints AND preconditioner turned on. When non-boundary constraints are present, you have to either a) use preconditioner, or b) use upper limit on step length. YOU CAN'T USE BOTH! In this case algorithm will terminate with appropriate error code. INPUT PARAMETERS: State - structure which stores algorithm state StpMax - maximum step length, >=0. Set StpMax to 0.0, if you don't want to limit step length. Use this subroutine when you optimize target function which contains exp() or other fast growing functions, and optimization algorithm makes too large steps which lead to overflow. This function allows us to reject steps that are too large (and therefore expose us to the possible overflow) without actually calculating function value at the x+stp*d. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minbleicsetstpmax(minbleicstate &state, const double stpmax, const xparams _xparams = alglib::xdefault);
minbleicsetxrep function/************************************************************************* This function turns on/off reporting. INPUT PARAMETERS: State - structure which stores algorithm state NeedXRep- whether iteration reports are needed or not If NeedXRep is True, algorithm will call rep() callback function if it is provided to MinBLEICOptimize(). -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleicsetxrep(minbleicstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_grad(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
// and its derivatives df/d0 and df/dx1
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
grad[0] = 400*pow(x[0]+3,3);
grad[1] = 4*pow(x[1]-3,3);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of
//
// f(x,y) = 100*(x+3)^4+(y-3)^4
//
// subject to box constraints
//
// -1<=x<=+1, -1<=y<=+1
//
// using BLEIC optimizer with:
// * initial point x=[0,0]
// * unit scale being set for all variables (see minbleicsetscale for more info)
// * stopping criteria set to "terminate after short enough step"
// * OptGuard integrity check being used to check problem statement
// for some common errors like nonsmoothness or bad analytic gradient
//
// First, we create optimizer object and tune its properties:
// * set box constraints
// * set variable scales
// * set stopping criteria
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
real_1d_array bndl = "[-1,-1]";
real_1d_array bndu = "[+1,+1]";
double epsg = 0;
double epsf = 0;
double epsx = 0.000001;
ae_int_t maxits = 0;
minbleicstate state;
minbleiccreate(x, state);
minbleicsetbc(state, bndl, bndu);
minbleicsetscale(state, s);
minbleicsetcond(state, epsg, epsf, epsx, maxits);
//
// Then we activate OptGuard integrity checking.
//
// OptGuard monitor helps to catch common coding and problem statement
// issues, like:
// * discontinuity of the target function (C0 continuity violation)
// * nonsmoothness of the target function (C1 continuity violation)
// * erroneous analytic gradient, i.e. one inconsistent with actual
// change in the target/constraints
//
// OptGuard is essential for early prototyping stages because such
// problems often result in premature termination of the optimizer
// which is really hard to distinguish from the correct termination.
//
// IMPORTANT: GRADIENT VERIFICATION IS PERFORMED BY MEANS OF NUMERICAL
// DIFFERENTIATION. DO NOT USE IT IN PRODUCTION CODE!!!!!!!
//
// Other OptGuard checks add moderate overhead, but anyway
// it is better to turn them off when they are not needed.
//
minbleicoptguardsmoothness(state);
minbleicoptguardgradient(state, 0.001);
//
// Optimize and evaluate results
//
minbleicreport rep;
alglib::minbleicoptimize(state, function1_grad);
minbleicresults(state, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 4
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-1,1]
//
// Check that OptGuard did not report errors
//
// NOTE: want to test OptGuard? Try breaking the gradient - say, add
// 1.0 to some of its components.
//
optguardreport ogrep;
minbleicoptguardresults(state, ogrep);
printf("%s\n", ogrep.badgradsuspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc0suspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc1suspected ? "true" : "false"); // EXPECTED: false
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_grad(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
// and its derivatives df/d0 and df/dx1
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
grad[0] = 400*pow(x[0]+3,3);
grad[1] = 4*pow(x[1]-3,3);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of
//
// f(x,y) = 100*(x+3)^4+(y-3)^4
//
// subject to inequality constraints
//
// * x>=2 (posed as general linear constraint),
// * x+y>=6
//
// using BLEIC optimizer with
// * initial point x=[0,0]
// * unit scale being set for all variables (see minbleicsetscale for more info)
// * stopping criteria set to "terminate after short enough step"
// * OptGuard integrity check being used to check problem statement
// for some common errors like nonsmoothness or bad analytic gradient
//
// First, we create optimizer object and tune its properties:
// * set linear constraints
// * set variable scales
// * set stopping criteria
//
real_1d_array x = "[5,5]";
real_1d_array s = "[1,1]";
real_2d_array c = "[[1,0,2],[1,1,6]]";
integer_1d_array ct = "[1,1]";
minbleicstate state;
double epsg = 0;
double epsf = 0;
double epsx = 0.000001;
ae_int_t maxits = 0;
minbleiccreate(x, state);
minbleicsetlc(state, c, ct);
minbleicsetscale(state, s);
minbleicsetcond(state, epsg, epsf, epsx, maxits);
//
// Then we activate OptGuard integrity checking.
//
// OptGuard monitor helps to catch common coding and problem statement
// issues, like:
// * discontinuity of the target function (C0 continuity violation)
// * nonsmoothness of the target function (C1 continuity violation)
// * erroneous analytic gradient, i.e. one inconsistent with actual
// change in the target/constraints
//
// OptGuard is essential for early prototyping stages because such
// problems often result in premature termination of the optimizer
// which is really hard to distinguish from the correct termination.
//
// IMPORTANT: GRADIENT VERIFICATION IS PERFORMED BY MEANS OF NUMERICAL
// DIFFERENTIATION. DO NOT USE IT IN PRODUCTION CODE!!!!!!!
//
// Other OptGuard checks add moderate overhead, but anyway
// it is better to turn them off when they are not needed.
//
minbleicoptguardsmoothness(state);
minbleicoptguardgradient(state, 0.001);
//
// Optimize and evaluate results
//
minbleicreport rep;
alglib::minbleicoptimize(state, function1_grad);
minbleicresults(state, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 4
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [2,4]
//
// Check that OptGuard did not report errors
//
// NOTE: want to test OptGuard? Try breaking the gradient - say, add
// 1.0 to some of its components.
//
optguardreport ogrep;
minbleicoptguardresults(state, ogrep);
printf("%s\n", ogrep.badgradsuspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc0suspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc1suspected ? "true" : "false"); // EXPECTED: false
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_func(const real_1d_array &x, double &func, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of
//
// f(x,y) = 100*(x+3)^4+(y-3)^4
//
// subject to box constraints
//
// -1<=x<=+1, -1<=y<=+1
//
// using BLEIC optimizer with:
// * numerical differentiation being used
// * initial point x=[0,0]
// * unit scale being set for all variables (see minbleicsetscale for more info)
// * stopping criteria set to "terminate after short enough step"
// * OptGuard integrity check being used to check problem statement
// for some common errors like nonsmoothness or bad analytic gradient
//
// First, we create optimizer object and tune its properties:
// * set box constraints
// * set variable scales
// * set stopping criteria
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
real_1d_array bndl = "[-1,-1]";
real_1d_array bndu = "[+1,+1]";
minbleicstate state;
double epsg = 0;
double epsf = 0;
double epsx = 0.000001;
ae_int_t maxits = 0;
double diffstep = 1.0e-6;
minbleiccreatef(x, diffstep, state);
minbleicsetbc(state, bndl, bndu);
minbleicsetscale(state, s);
minbleicsetcond(state, epsg, epsf, epsx, maxits);
//
// Then we activate OptGuard integrity checking.
//
// Numerical differentiation always produces "correct" gradient
// (with some truncation error, but unbiased). Thus, we just have
// to check smoothness properties of the target: C0 and C1 continuity.
//
// Sometimes user accidentally tries to solve nonsmooth problems
// with smooth optimizer. OptGuard helps to detect such situations
// early, at the prototyping stage.
//
minbleicoptguardsmoothness(state);
//
// Optimize and evaluate results
//
minbleicreport rep;
alglib::minbleicoptimize(state, function1_func);
minbleicresults(state, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 4
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-1,1]
//
// Check that OptGuard did not report errors
//
// Want to challenge OptGuard? Try to make your problem
// nonsmooth by replacing 100*(x+3)^4 by 100*|x+3| and
// re-run optimizer.
//
optguardreport ogrep;
minbleicoptguardresults(state, ogrep);
printf("%s\n", ogrep.nonc0suspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc1suspected ? "true" : "false"); // EXPECTED: false
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
mincg subpackage| mincg_d_1 | Nonlinear optimization by CG | |
| mincg_d_2 | Nonlinear optimization with additional settings and restarts | |
| mincg_numdiff | Nonlinear optimization by CG with numerical differentiation |
mincgreport class/************************************************************************* This structure stores optimization report: * IterationsCount total number of inner iterations * NFEV number of gradient evaluations * TerminationType termination type (see below) TERMINATION CODES TerminationType field contains completion code, which can be: -8 internal integrity control detected infinite or NAN values in function/gradient. Abnormal termination signalled. 1 relative function improvement is no more than EpsF. 2 relative step is no more than EpsX. 4 gradient norm is no more than EpsG 5 MaxIts steps was taken 7 stopping conditions are too stringent, further improvement is impossible, X contains best point found so far. 8 terminated by user who called mincgrequesttermination(). X contains point which was "current accepted" when termination request was submitted. Other fields of this structure are not documented and should not be used! *************************************************************************/class mincgreport { public: mincgreport(); mincgreport(const mincgreport &rhs); mincgreport& operator=(const mincgreport &rhs); virtual ~mincgreport(); ae_int_t iterationscount; ae_int_t nfev; ae_int_t terminationtype; };
mincgstate class/************************************************************************* This object stores state of the nonlinear CG optimizer. You should use ALGLIB functions to work with this object. *************************************************************************/class mincgstate { public: mincgstate(); mincgstate(const mincgstate &rhs); mincgstate& operator=(const mincgstate &rhs); virtual ~mincgstate(); };
mincgcreate function/************************************************************************* NONLINEAR CONJUGATE GRADIENT METHOD DESCRIPTION: The subroutine minimizes function F(x) of N arguments by using one of the nonlinear conjugate gradient methods. These CG methods are globally convergent (even on non-convex functions) as long as grad(f) is Lipschitz continuous in a some neighborhood of the L = { x : f(x)<=f(x0) }. REQUIREMENTS: Algorithm will request following information during its operation: * function value F and its gradient G (simultaneously) at given point X USAGE: 1. User initializes algorithm state with MinCGCreate() call 2. User tunes solver parameters with MinCGSetCond(), MinCGSetStpMax() and other functions 3. User calls MinCGOptimize() function which takes algorithm state and pointer (delegate, etc.) to callback function which calculates F/G. 4. User calls MinCGResults() to get solution 5. Optionally, user may call MinCGRestartFrom() to solve another problem with same N but another starting point and/or another function. MinCGRestartFrom() allows to reuse already initialized structure. INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of X are used * if not given, automatically determined from size of X X - starting point, array[0..N-1]. OUTPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 25.03.2010 by Bochkanov Sergey *************************************************************************/void mincgcreate(const ae_int_t n, const real_1d_array &x, mincgstate &state, const xparams _xparams = alglib::xdefault); void mincgcreate(const real_1d_array &x, mincgstate &state, const xparams _xparams = alglib::xdefault);
mincgcreatef function/************************************************************************* The subroutine is finite difference variant of MinCGCreate(). It uses finite differences in order to differentiate target function. Description below contains information which is specific to this function only. We recommend to read comments on MinCGCreate() in order to get more information about creation of CG optimizer. INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of X are used * if not given, automatically determined from size of X X - starting point, array[0..N-1]. DiffStep- differentiation step, >0 OUTPUT PARAMETERS: State - structure which stores algorithm state NOTES: 1. algorithm uses 4-point central formula for differentiation. 2. differentiation step along I-th axis is equal to DiffStep*S[I] where S[] is scaling vector which can be set by MinCGSetScale() call. 3. we recommend you to use moderate values of differentiation step. Too large step will result in too large truncation errors, while too small step will result in too large numerical errors. 1.0E-6 can be good value to start with. 4. Numerical differentiation is very inefficient - one gradient calculation needs 4*N function evaluations. This function will work for any N - either small (1...10), moderate (10...100) or large (100...). However, performance penalty will be too severe for any N's except for small ones. We should also say that code which relies on numerical differentiation is less robust and precise. L-BFGS needs exact gradient values. Imprecise gradient may slow down convergence, especially on highly nonlinear problems. Thus we recommend to use this function for fast prototyping on small- dimensional problems only, and to implement analytical gradient as soon as possible. -- ALGLIB -- Copyright 16.05.2011 by Bochkanov Sergey *************************************************************************/void mincgcreatef(const ae_int_t n, const real_1d_array &x, const double diffstep, mincgstate &state, const xparams _xparams = alglib::xdefault); void mincgcreatef(const real_1d_array &x, const double diffstep, mincgstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
mincgiteration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool mincgiteration(mincgstate &state, const xparams _xparams = alglib::xdefault);
mincgoptguardgradient function/************************************************************************* This function activates/deactivates verification of the user-supplied analytic gradient. Upon activation of this option OptGuard integrity checker performs numerical differentiation of your target function at the initial point (note: future versions may also perform check at the final point) and compares numerical gradient with analytic one provided by you. If difference is too large, an error flag is set and optimization session continues. After optimization session is over, you can retrieve the report which stores both gradients and specific components highlighted as suspicious by the OptGuard. The primary OptGuard report can be retrieved with mincgoptguardresults(). IMPORTANT: gradient check is a high-overhead option which will cost you about 3*N additional function evaluations. In many cases it may cost as much as the rest of the optimization session. YOU SHOULD NOT USE IT IN THE PRODUCTION CODE UNLESS YOU WANT TO CHECK DERIVATIVES PROVIDED BY SOME THIRD PARTY. NOTE: unlike previous incarnation of the gradient checking code, OptGuard does NOT interrupt optimization even if it discovers bad gradient. INPUT PARAMETERS: State - structure used to store algorithm state TestStep - verification step used for numerical differentiation: * TestStep=0 turns verification off * TestStep>0 activates verification You should carefully choose TestStep. Value which is too large (so large that function behavior is non- cubic at this scale) will lead to false alarms. Too short step will result in rounding errors dominating numerical derivative. You may use different step for different parameters by means of setting scale with mincgsetscale(). === EXPLANATION ========================================================== In order to verify gradient algorithm performs following steps: * two trial steps are made to X[i]-TestStep*S[i] and X[i]+TestStep*S[i], where X[i] is i-th component of the initial point and S[i] is a scale of i-th parameter * F(X) is evaluated at these trial points * we perform one more evaluation in the middle point of the interval * we build cubic model using function values and derivatives at trial points and we compare its prediction with actual value in the middle point -- ALGLIB -- Copyright 15.06.2014 by Bochkanov Sergey *************************************************************************/void mincgoptguardgradient(mincgstate &state, const double teststep, const xparams _xparams = alglib::xdefault);
Examples: [1]
mincgoptguardnonc1test0results function/************************************************************************* Detailed results of the OptGuard integrity check for nonsmoothness test #0 Nonsmoothness (non-C1) test #0 studies function values (not gradient!) obtained during line searches and monitors behavior of the directional derivative estimate. This test is less powerful than test #1, but it does not depend on the gradient values and thus it is more robust against artifacts introduced by numerical differentiation. Two reports are returned: * a "strongest" one, corresponding to line search which had highest value of the nonsmoothness indicator * a "longest" one, corresponding to line search which had more function evaluations, and thus is more detailed In both cases following fields are returned: * positive - is TRUE when test flagged suspicious point; FALSE if test did not notice anything (in the latter cases fields below are empty). * x0[], d[] - arrays of length N which store initial point and direction for line search (d[] can be normalized, but does not have to) * stp[], f[] - arrays of length CNT which store step lengths and function values at these points; f[i] is evaluated in x0+stp[i]*d. * stpidxa, stpidxb - we suspect that function violates C1 continuity between steps #stpidxa and #stpidxb (usually we have stpidxb=stpidxa+3, with most likely position of the violation between stpidxa+1 and stpidxa+2. ========================================================================== = SHORTLY SPEAKING: build a 2D plot of (stp,f) and look at it - you will = see where C1 continuity is violated. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: strrep - C1 test #0 "strong" report lngrep - C1 test #0 "long" report -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void mincgoptguardnonc1test0results(const mincgstate &state, optguardnonc1test0report &strrep, optguardnonc1test0report &lngrep, const xparams _xparams = alglib::xdefault);
mincgoptguardnonc1test1results function/************************************************************************* Detailed results of the OptGuard integrity check for nonsmoothness test #1 Nonsmoothness (non-C1) test #1 studies individual components of the gradient computed during line search. When precise analytic gradient is provided this test is more powerful than test #0 which works with function values and ignores user-provided gradient. However, test #0 becomes more powerful when numerical differentiation is employed (in such cases test #1 detects higher levels of numerical noise and becomes too conservative). This test also tells specific components of the gradient which violate C1 continuity, which makes it more informative than #0, which just tells that continuity is violated. Two reports are returned: * a "strongest" one, corresponding to line search which had highest value of the nonsmoothness indicator * a "longest" one, corresponding to line search which had more function evaluations, and thus is more detailed In both cases following fields are returned: * positive - is TRUE when test flagged suspicious point; FALSE if test did not notice anything (in the latter cases fields below are empty). * vidx - is an index of the variable in [0,N) with nonsmooth derivative * x0[], d[] - arrays of length N which store initial point and direction for line search (d[] can be normalized, but does not have to) * stp[], g[] - arrays of length CNT which store step lengths and gradient values at these points; g[i] is evaluated in x0+stp[i]*d and contains vidx-th component of the gradient. * stpidxa, stpidxb - we suspect that function violates C1 continuity between steps #stpidxa and #stpidxb (usually we have stpidxb=stpidxa+3, with most likely position of the violation between stpidxa+1 and stpidxa+2. ========================================================================== = SHORTLY SPEAKING: build a 2D plot of (stp,f) and look at it - you will = see where C1 continuity is violated. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: strrep - C1 test #1 "strong" report lngrep - C1 test #1 "long" report -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void mincgoptguardnonc1test1results(mincgstate &state, optguardnonc1test1report &strrep, optguardnonc1test1report &lngrep, const xparams _xparams = alglib::xdefault);
mincgoptguardresults function/************************************************************************* Results of OptGuard integrity check, should be called after optimization session is over. === PRIMARY REPORT ======================================================= OptGuard performs several checks which are intended to catch common errors in the implementation of nonlinear function/gradient: * incorrect analytic gradient * discontinuous (non-C0) target functions (constraints) * nonsmooth (non-C1) target functions (constraints) Each of these checks is activated with appropriate function: * mincgoptguardgradient() for gradient verification * mincgoptguardsmoothness() for C0/C1 checks Following flags are set when these errors are suspected: * rep.badgradsuspected, and additionally: * rep.badgradvidx for specific variable (gradient element) suspected * rep.badgradxbase, a point where gradient is tested * rep.badgraduser, user-provided gradient (stored as 2D matrix with single row in order to make report structure compatible with more complex optimizers like MinNLC or MinLM) * rep.badgradnum, reference gradient obtained via numerical differentiation (stored as 2D matrix with single row in order to make report structure compatible with more complex optimizers like MinNLC or MinLM) * rep.nonc0suspected * rep.nonc1suspected === ADDITIONAL REPORTS/LOGS ============================================== Several different tests are performed to catch C0/C1 errors, you can find out specific test signaled error by looking to: * rep.nonc0test0positive, for non-C0 test #0 * rep.nonc1test0positive, for non-C1 test #0 * rep.nonc1test1positive, for non-C1 test #1 Additional information (including line search logs) can be obtained by means of: * mincgoptguardnonc1test0results() * mincgoptguardnonc1test1results() which return detailed error reports, specific points where discontinuities were found, and so on. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: rep - generic OptGuard report; more detailed reports can be retrieved with other functions. NOTE: false negatives (nonsmooth problems are not identified as nonsmooth ones) are possible although unlikely. The reason is that you need to make several evaluations around nonsmoothness in order to accumulate enough information about function curvature. Say, if you start right from the nonsmooth point, optimizer simply won't get enough data to understand what is going wrong before it terminates due to abrupt changes in the derivative. It is also possible that "unlucky" step will move us to the termination too quickly. Our current approach is to have less than 0.1% false negatives in our test examples (measured with multiple restarts from random points), and to have exactly 0% false positives. -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void mincgoptguardresults(mincgstate &state, optguardreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
mincgoptguardsmoothness function/************************************************************************* This function activates/deactivates nonsmoothness monitoring option of the OptGuard integrity checker. Smoothness monitor silently observes solution process and tries to detect ill-posed problems, i.e. ones with: a) discontinuous target function (non-C0) b) nonsmooth target function (non-C1) Smoothness monitoring does NOT interrupt optimization even if it suspects that your problem is nonsmooth. It just sets corresponding flags in the OptGuard report which can be retrieved after optimization is over. Smoothness monitoring is a moderate overhead option which often adds less than 1% to the optimizer running time. Thus, you can use it even for large scale problems. NOTE: OptGuard does NOT guarantee that it will always detect C0/C1 continuity violations. First, minor errors are hard to catch - say, a 0.0001 difference in the model values at two sides of the gap may be due to discontinuity of the model - or simply because the model has changed. Second, C1-violations are especially difficult to detect in a noninvasive way. The optimizer usually performs very short steps near the nonsmoothness, and differentiation usually introduces a lot of numerical noise. It is hard to tell whether some tiny discontinuity in the slope is due to real nonsmoothness or just due to numerical noise alone. Our top priority was to avoid false positives, so in some rare cases minor errors may went unnoticed (however, in most cases they can be spotted with restart from different initial point). INPUT PARAMETERS: state - algorithm state level - monitoring level: * 0 - monitoring is disabled * 1 - noninvasive low-overhead monitoring; function values and/or gradients are recorded, but OptGuard does not try to perform additional evaluations in order to get more information about suspicious locations. === EXPLANATION ========================================================== One major source of headache during optimization is the possibility of the coding errors in the target function/constraints (or their gradients). Such errors most often manifest themselves as discontinuity or nonsmoothness of the target/constraints. Another frequent situation is when you try to optimize something involving lots of min() and max() operations, i.e. nonsmooth target. Although not a coding error, it is nonsmoothness anyway - and smooth optimizers usually stop right after encountering nonsmoothness, well before reaching solution. OptGuard integrity checker helps you to catch such situations: it monitors function values/gradients being passed to the optimizer and tries to errors. Upon discovering suspicious pair of points it raises appropriate flag (and allows you to continue optimization). When optimization is done, you can study OptGuard result. -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void mincgoptguardsmoothness(mincgstate &state, const ae_int_t level, const xparams _xparams = alglib::xdefault); void mincgoptguardsmoothness(mincgstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
mincgoptimize function/************************************************************************* This family of functions is used to start iterations of nonlinear optimizer These functions accept following parameters: state - algorithm state func - callback which calculates function (or merit function) value func at given point x grad - callback which calculates function (or merit function) value func and gradient grad at given point x rep - optional callback which is called after each iteration can be NULL ptr - optional pointer which is passed to func/grad/hess/jac/rep can be NULL NOTES: 1. This function has two different implementations: one which uses exact (analytical) user-supplied gradient, and one which uses function value only and numerically differentiates function in order to obtain gradient. Depending on the specific function used to create optimizer object (either MinCGCreate() for analytical gradient or MinCGCreateF() for numerical differentiation) you should choose appropriate variant of MinCGOptimize() - one which accepts function AND gradient or one which accepts function ONLY. Be careful to choose variant of MinCGOptimize() which corresponds to your optimization scheme! Table below lists different combinations of callback (function/gradient) passed to MinCGOptimize() and specific function used to create optimizer. | USER PASSED TO MinCGOptimize() CREATED WITH | function only | function and gradient ------------------------------------------------------------ MinCGCreateF() | work FAIL MinCGCreate() | FAIL work Here "FAIL" denotes inappropriate combinations of optimizer creation function and MinCGOptimize() version. Attemps to use such combination (for example, to create optimizer with MinCGCreateF() and to pass gradient information to MinCGOptimize()) will lead to exception being thrown. Either you did not pass gradient when it WAS needed or you passed gradient when it was NOT needed. -- ALGLIB -- Copyright 20.04.2009 by Bochkanov Sergey *************************************************************************/void mincgoptimize(mincgstate &state, void (*func)(const real_1d_array &x, double &func, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault); void mincgoptimize(mincgstate &state, void (*grad)(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault);
mincgrequesttermination function/************************************************************************* This subroutine submits request for termination of running optimizer. It should be called from user-supplied callback when user decides that it is time to "smoothly" terminate optimization process. As result, optimizer stops at point which was "current accepted" when termination request was submitted and returns error code 8 (successful termination). INPUT PARAMETERS: State - optimizer structure NOTE: after request for termination optimizer may perform several additional calls to user-supplied callbacks. It does NOT guarantee to stop immediately - it just guarantees that these additional calls will be discarded later. NOTE: calling this function on optimizer which is NOT running will have no effect. NOTE: multiple calls to this function are possible. First call is counted, subsequent calls are silently ignored. -- ALGLIB -- Copyright 08.10.2014 by Bochkanov Sergey *************************************************************************/void mincgrequesttermination(mincgstate &state, const xparams _xparams = alglib::xdefault);
mincgrestartfrom function/************************************************************************* This subroutine restarts CG algorithm from new point. All optimization parameters are left unchanged. This function allows to solve multiple optimization problems (which must have same number of dimensions) without object reallocation penalty. INPUT PARAMETERS: State - structure used to store algorithm state. X - new starting point. -- ALGLIB -- Copyright 30.07.2010 by Bochkanov Sergey *************************************************************************/void mincgrestartfrom(mincgstate &state, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
Examples: [1]
mincgresults function/************************************************************************* Conjugate gradient results INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: X - array[0..N-1], solution Rep - optimization report: * Rep.TerminationType completetion code: * -8 internal integrity control detected infinite or NAN values in function/gradient. Abnormal termination signalled. * -7 gradient verification failed. See MinCGSetGradientCheck() for more information. * 1 relative function improvement is no more than EpsF. * 2 relative step is no more than EpsX. * 4 gradient norm is no more than EpsG * 5 MaxIts steps was taken * 7 stopping conditions are too stringent, further improvement is impossible, we return best X found so far * 8 terminated by user * Rep.IterationsCount contains iterations count * NFEV countains number of function calculations -- ALGLIB -- Copyright 20.04.2009 by Bochkanov Sergey *************************************************************************/void mincgresults(const mincgstate &state, real_1d_array &x, mincgreport &rep, const xparams _xparams = alglib::xdefault);
mincgresultsbuf function/************************************************************************* Conjugate gradient results Buffered implementation of MinCGResults(), which uses pre-allocated buffer to store X[]. If buffer size is too small, it resizes buffer. It is intended to be used in the inner cycles of performance critical algorithms where array reallocation penalty is too large to be ignored. -- ALGLIB -- Copyright 20.04.2009 by Bochkanov Sergey *************************************************************************/void mincgresultsbuf(const mincgstate &state, real_1d_array &x, mincgreport &rep, const xparams _xparams = alglib::xdefault);
mincgsetcgtype function/************************************************************************* This function sets CG algorithm. INPUT PARAMETERS: State - structure which stores algorithm state CGType - algorithm type: * -1 automatic selection of the best algorithm * 0 DY (Dai and Yuan) algorithm * 1 Hybrid DY-HS algorithm -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void mincgsetcgtype(mincgstate &state, const ae_int_t cgtype, const xparams _xparams = alglib::xdefault);
mincgsetcond function/************************************************************************* This function sets stopping conditions for CG optimization algorithm. INPUT PARAMETERS: State - structure which stores algorithm state EpsG - >=0 The subroutine finishes its work if the condition |v|<EpsG is satisfied, where: * |.| means Euclidian norm * v - scaled gradient vector, v[i]=g[i]*s[i] * g - gradient * s - scaling coefficients set by MinCGSetScale() EpsF - >=0 The subroutine finishes its work if on k+1-th iteration the condition |F(k+1)-F(k)|<=EpsF*max{|F(k)|,|F(k+1)|,1} is satisfied. EpsX - >=0 The subroutine finishes its work if on k+1-th iteration the condition |v|<=EpsX is fulfilled, where: * |.| means Euclidian norm * v - scaled step vector, v[i]=dx[i]/s[i] * dx - ste pvector, dx=X(k+1)-X(k) * s - scaling coefficients set by MinCGSetScale() MaxIts - maximum number of iterations. If MaxIts=0, the number of iterations is unlimited. Passing EpsG=0, EpsF=0, EpsX=0 and MaxIts=0 (simultaneously) will lead to automatic stopping criterion selection (small EpsX). -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void mincgsetcond(mincgstate &state, const double epsg, const double epsf, const double epsx, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
mincgsetprecdefault function/************************************************************************* Modification of the preconditioner: preconditioning is turned off. INPUT PARAMETERS: State - structure which stores algorithm state NOTE: you can change preconditioner "on the fly", during algorithm iterations. -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void mincgsetprecdefault(mincgstate &state, const xparams _xparams = alglib::xdefault);
mincgsetprecdiag function/************************************************************************* Modification of the preconditioner: diagonal of approximate Hessian is used. INPUT PARAMETERS: State - structure which stores algorithm state D - diagonal of the approximate Hessian, array[0..N-1], (if larger, only leading N elements are used). NOTE: you can change preconditioner "on the fly", during algorithm iterations. NOTE 2: D[i] should be positive. Exception will be thrown otherwise. NOTE 3: you should pass diagonal of approximate Hessian - NOT ITS INVERSE. -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void mincgsetprecdiag(mincgstate &state, const real_1d_array &d, const xparams _xparams = alglib::xdefault);
mincgsetprecscale function/************************************************************************* Modification of the preconditioner: scale-based diagonal preconditioning. This preconditioning mode can be useful when you don't have approximate diagonal of Hessian, but you know that your variables are badly scaled (for example, one variable is in [1,10], and another in [1000,100000]), and most part of the ill-conditioning comes from different scales of vars. In this case simple scale-based preconditioner, with H[i] = 1/(s[i]^2), can greatly improve convergence. IMPRTANT: you should set scale of your variables with MinCGSetScale() call (before or after MinCGSetPrecScale() call). Without knowledge of the scale of your variables scale-based preconditioner will be just unit matrix. INPUT PARAMETERS: State - structure which stores algorithm state NOTE: you can change preconditioner "on the fly", during algorithm iterations. -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void mincgsetprecscale(mincgstate &state, const xparams _xparams = alglib::xdefault);
mincgsetscale function/************************************************************************* This function sets scaling coefficients for CG optimizer. ALGLIB optimizers use scaling matrices to test stopping conditions (step size and gradient are scaled before comparison with tolerances). Scale of the I-th variable is a translation invariant measure of: a) "how large" the variable is b) how large the step should be to make significant changes in the function Scaling is also used by finite difference variant of CG optimizer - step along I-th axis is equal to DiffStep*S[I]. In most optimizers (and in the CG too) scaling is NOT a form of preconditioning. It just affects stopping conditions. You should set preconditioner by separate call to one of the MinCGSetPrec...() functions. There is special preconditioning mode, however, which uses scaling coefficients to form diagonal preconditioning matrix. You can turn this mode on, if you want. But you should understand that scaling is not the same thing as preconditioning - these are two different, although related forms of tuning solver. INPUT PARAMETERS: State - structure stores algorithm state S - array[N], non-zero scaling coefficients S[i] may be negative, sign doesn't matter. -- ALGLIB -- Copyright 14.01.2011 by Bochkanov Sergey *************************************************************************/void mincgsetscale(mincgstate &state, const real_1d_array &s, const xparams _xparams = alglib::xdefault);
mincgsetstpmax function/************************************************************************* This function sets maximum step length INPUT PARAMETERS: State - structure which stores algorithm state StpMax - maximum step length, >=0. Set StpMax to 0.0, if you don't want to limit step length. Use this subroutine when you optimize target function which contains exp() or other fast growing functions, and optimization algorithm makes too large steps which leads to overflow. This function allows us to reject steps that are too large (and therefore expose us to the possible overflow) without actually calculating function value at the x+stp*d. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void mincgsetstpmax(mincgstate &state, const double stpmax, const xparams _xparams = alglib::xdefault);
mincgsetxrep function/************************************************************************* This function turns on/off reporting. INPUT PARAMETERS: State - structure which stores algorithm state NeedXRep- whether iteration reports are needed or not If NeedXRep is True, algorithm will call rep() callback function if it is provided to MinCGOptimize(). -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void mincgsetxrep(mincgstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
mincgsuggeststep function/************************************************************************* This function allows to suggest initial step length to the CG algorithm. Suggested step length is used as starting point for the line search. It can be useful when you have badly scaled problem, i.e. when ||grad|| (which is used as initial estimate for the first step) is many orders of magnitude different from the desired step. Line search may fail on such problems without good estimate of initial step length. Imagine, for example, problem with ||grad||=10^50 and desired step equal to 0.1 Line search function will use 10^50 as initial step, then it will decrease step length by 2 (up to 20 attempts) and will get 10^44, which is still too large. This function allows us to tell than line search should be started from some moderate step length, like 1.0, so algorithm will be able to detect desired step length in a several searches. Default behavior (when no step is suggested) is to use preconditioner, if it is available, to generate initial estimate of step length. This function influences only first iteration of algorithm. It should be called between MinCGCreate/MinCGRestartFrom() call and MinCGOptimize call. Suggested step is ignored if you have preconditioner. INPUT PARAMETERS: State - structure used to store algorithm state. Stp - initial estimate of the step length. Can be zero (no estimate). -- ALGLIB -- Copyright 30.07.2010 by Bochkanov Sergey *************************************************************************/void mincgsuggeststep(mincgstate &state, const double stp, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_grad(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
// and its derivatives df/d0 and df/dx1
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
grad[0] = 400*pow(x[0]+3,3);
grad[1] = 4*pow(x[1]-3,3);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of
//
// f(x,y) = 100*(x+3)^4+(y-3)^4
//
// using nonlinear conjugate gradient method with:
// * initial point x=[0,0]
// * unit scale being set for all variables (see mincgsetscale for more info)
// * stopping criteria set to "terminate after short enough step"
// * OptGuard integrity check being used to check problem statement
// for some common errors like nonsmoothness or bad analytic gradient
//
// First, we create optimizer object and tune its properties
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
double epsg = 0;
double epsf = 0;
double epsx = 0.0000000001;
ae_int_t maxits = 0;
mincgstate state;
mincgcreate(x, state);
mincgsetcond(state, epsg, epsf, epsx, maxits);
mincgsetscale(state, s);
//
// Activate OptGuard integrity checking.
//
// OptGuard monitor helps to catch common coding and problem statement
// issues, like:
// * discontinuity of the target function (C0 continuity violation)
// * nonsmoothness of the target function (C1 continuity violation)
// * erroneous analytic gradient, i.e. one inconsistent with actual
// change in the target/constraints
//
// OptGuard is essential for early prototyping stages because such
// problems often result in premature termination of the optimizer
// which is really hard to distinguish from the correct termination.
//
// IMPORTANT: GRADIENT VERIFICATION IS PERFORMED BY MEANS OF NUMERICAL
// DIFFERENTIATION. DO NOT USE IT IN PRODUCTION CODE!!!!!!!
//
// Other OptGuard checks add moderate overhead, but anyway
// it is better to turn them off when they are not needed.
//
mincgoptguardsmoothness(state);
mincgoptguardgradient(state, 0.001);
//
// Optimize and evaluate results
//
mincgreport rep;
alglib::mincgoptimize(state, function1_grad);
mincgresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,3]
//
// Check that OptGuard did not report errors
//
// NOTE: want to test OptGuard? Try breaking the gradient - say, add
// 1.0 to some of its components.
//
optguardreport ogrep;
mincgoptguardresults(state, ogrep);
printf("%s\n", ogrep.badgradsuspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc0suspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc1suspected ? "true" : "false"); // EXPECTED: false
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_grad(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
// and its derivatives df/d0 and df/dx1
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
grad[0] = 400*pow(x[0]+3,3);
grad[1] = 4*pow(x[1]-3,3);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of f(x,y) = 100*(x+3)^4+(y-3)^4
// with nonlinear conjugate gradient method.
//
// Several advanced techniques are demonstrated:
// * upper limit on step size
// * restart from new point
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
double epsg = 0;
double epsf = 0;
double epsx = 0.0000000001;
double stpmax = 0.1;
ae_int_t maxits = 0;
mincgstate state;
mincgreport rep;
// create and tune optimizer
mincgcreate(x, state);
mincgsetscale(state, s);
mincgsetcond(state, epsg, epsf, epsx, maxits);
mincgsetstpmax(state, stpmax);
// Set up OptGuard integrity checker which catches errors
// like nonsmooth targets or errors in the analytic gradient.
//
// OptGuard is essential at the early prototyping stages.
//
// NOTE: gradient verification needs 3*N additional function
// evaluations; DO NOT USE IT IN THE PRODUCTION CODE
// because it leads to unnecessary slowdown of your app.
mincgoptguardsmoothness(state);
mincgoptguardgradient(state, 0.001);
// first run
alglib::mincgoptimize(state, function1_grad);
mincgresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,3]
// second run - algorithm is restarted with mincgrestartfrom()
x = "[10,10]";
mincgrestartfrom(state, x);
alglib::mincgoptimize(state, function1_grad);
mincgresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,3]
// check OptGuard integrity report. Why do we need it at all?
// Well, try breaking the gradient by adding 1.0 to some
// of its components - OptGuard should report it as error.
// And it may also catch unintended errors too :)
optguardreport ogrep;
mincgoptguardresults(state, ogrep);
printf("%s\n", ogrep.badgradsuspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc0suspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc1suspected ? "true" : "false"); // EXPECTED: false
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_func(const real_1d_array &x, double &func, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of
//
// f(x,y) = 100*(x+3)^4+(y-3)^4
//
// using numerical differentiation to calculate gradient.
//
// We also show how to use OptGuard integrity checker to catch common
// problem statement errors like accidentally specifying nonsmooth target
// function.
//
// First, we set up optimizer...
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
double epsg = 0;
double epsf = 0;
double epsx = 0.0000000001;
double diffstep = 1.0e-6;
ae_int_t maxits = 0;
mincgstate state;
mincgcreatef(x, diffstep, state);
mincgsetcond(state, epsg, epsf, epsx, maxits);
mincgsetscale(state, s);
//
// Then, we activate OptGuard integrity checking.
//
// Numerical differentiation always produces "correct" gradient
// (with some truncation error, but unbiased). Thus, we just have
// to check smoothness properties of the target: C0 and C1 continuity.
//
// Sometimes user accidentally tried to solve nonsmooth problems
// with smooth optimizer. OptGuard helps to detect such situations
// early, at the prototyping stage.
//
mincgoptguardsmoothness(state);
//
// Now we are ready to run the optimization
//
mincgreport rep;
alglib::mincgoptimize(state, function1_func);
mincgresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,3]
//
// ...and to check OptGuard integrity report.
//
// Want to challenge OptGuard? Try to make your problem
// nonsmooth by replacing 100*(x+3)^4 by 100*|x+3| and
// re-run optimizer.
//
optguardreport ogrep;
mincgoptguardresults(state, ogrep);
printf("%s\n", ogrep.nonc0suspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc1suspected ? "true" : "false"); // EXPECTED: false
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
mincomp subpackageminasareport class/************************************************************************* *************************************************************************/class minasareport { public: minasareport(); minasareport(const minasareport &rhs); minasareport& operator=(const minasareport &rhs); virtual ~minasareport(); ae_int_t iterationscount; ae_int_t nfev; ae_int_t terminationtype; ae_int_t activeconstraints; };
minasastate class/************************************************************************* *************************************************************************/class minasastate { public: minasastate(); minasastate(const minasastate &rhs); minasastate& operator=(const minasastate &rhs); virtual ~minasastate(); };
minasacreate function/************************************************************************* Obsolete optimization algorithm. Was replaced by MinBLEIC subpackage. -- ALGLIB -- Copyright 25.03.2010 by Bochkanov Sergey *************************************************************************/void minasacreate(const ae_int_t n, const real_1d_array &x, const real_1d_array &bndl, const real_1d_array &bndu, minasastate &state, const xparams _xparams = alglib::xdefault); void minasacreate(const real_1d_array &x, const real_1d_array &bndl, const real_1d_array &bndu, minasastate &state, const xparams _xparams = alglib::xdefault);
minasaiteration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool minasaiteration(minasastate &state, const xparams _xparams = alglib::xdefault);
minasaoptimize function/************************************************************************* This family of functions is used to start iterations of nonlinear optimizer These functions accept following parameters: state - algorithm state grad - callback which calculates function (or merit function) value func and gradient grad at given point x rep - optional callback which is called after each iteration can be NULL ptr - optional pointer which is passed to func/grad/hess/jac/rep can be NULL -- ALGLIB -- Copyright 20.03.2009 by Bochkanov Sergey *************************************************************************/void minasaoptimize(minasastate &state, void (*grad)(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault);
minasarestartfrom function/************************************************************************* Obsolete optimization algorithm. Was replaced by MinBLEIC subpackage. -- ALGLIB -- Copyright 30.07.2010 by Bochkanov Sergey *************************************************************************/void minasarestartfrom(minasastate &state, const real_1d_array &x, const real_1d_array &bndl, const real_1d_array &bndu, const xparams _xparams = alglib::xdefault);
minasaresults function/************************************************************************* Obsolete optimization algorithm. Was replaced by MinBLEIC subpackage. -- ALGLIB -- Copyright 20.03.2009 by Bochkanov Sergey *************************************************************************/void minasaresults(const minasastate &state, real_1d_array &x, minasareport &rep, const xparams _xparams = alglib::xdefault);
minasaresultsbuf function/************************************************************************* Obsolete optimization algorithm. Was replaced by MinBLEIC subpackage. -- ALGLIB -- Copyright 20.03.2009 by Bochkanov Sergey *************************************************************************/void minasaresultsbuf(const minasastate &state, real_1d_array &x, minasareport &rep, const xparams _xparams = alglib::xdefault);
minasasetalgorithm function/************************************************************************* Obsolete optimization algorithm. Was replaced by MinBLEIC subpackage. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minasasetalgorithm(minasastate &state, const ae_int_t algotype, const xparams _xparams = alglib::xdefault);
minasasetcond function/************************************************************************* Obsolete optimization algorithm. Was replaced by MinBLEIC subpackage. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minasasetcond(minasastate &state, const double epsg, const double epsf, const double epsx, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
minasasetstpmax function/************************************************************************* Obsolete optimization algorithm. Was replaced by MinBLEIC subpackage. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minasasetstpmax(minasastate &state, const double stpmax, const xparams _xparams = alglib::xdefault);
minasasetxrep function/************************************************************************* Obsolete optimization algorithm. Was replaced by MinBLEIC subpackage. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minasasetxrep(minasastate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
minbleicsetbarrierdecay function/************************************************************************* This is obsolete function which was used by previous version of the BLEIC optimizer. It does nothing in the current version of BLEIC. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleicsetbarrierdecay(minbleicstate &state, const double mudecay, const xparams _xparams = alglib::xdefault);
minbleicsetbarrierwidth function/************************************************************************* This is obsolete function which was used by previous version of the BLEIC optimizer. It does nothing in the current version of BLEIC. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minbleicsetbarrierwidth(minbleicstate &state, const double mu, const xparams _xparams = alglib::xdefault);
minlbfgssetcholeskypreconditioner function/************************************************************************* Obsolete function, use MinLBFGSSetCholeskyPreconditioner() instead. -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minlbfgssetcholeskypreconditioner(minlbfgsstate &state, const real_2d_array &p, const bool isupper, const xparams _xparams = alglib::xdefault);
minlbfgssetdefaultpreconditioner function/************************************************************************* Obsolete function, use MinLBFGSSetPrecDefault() instead. -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minlbfgssetdefaultpreconditioner(minlbfgsstate &state, const xparams _xparams = alglib::xdefault);
mindf subpackage| mindf_gdemo_auto | Nonlinearly constrained differential evolution |
mindfreport class/************************************************************************* This structure stores optimization report: * f objective value at the solution * iterationscount total number of inner iterations * nfev number of gradient evaluations * terminationtype termination type (see below) * bcerr maximum violation of box constraints * lcerr maximum violation of linear constraints * nlcerr maximum violation of nonlinear constraints If timers were activated, the structure also stores running times: * timesolver time (in seconds, stored as a floating-point value) spent in the solver itself. Time spent in the user callback is not included. See 'TIMERS' below for more information. * timecallback time (in seconds, stored as a floating-point value) spent in the user callback. See 'TIMERS' below for more information. * timetotal total time spent during the optimization, including both the solver and callbacks. See 'TIMERS' below for more information. In order to activate timers, the caller has to call mindfusetimers() function. Other fields of this structure are not documented and should not be used! TERMINATION CODES TerminationType field contains completion code, which can be: -8 internal integrity control detected infinite or NAN values in function/gradient. Abnormal termination signalled. -3 box constraints are inconsistent -1 inconsistent parameters were passed: * penalty parameter is zero, but we have nonlinear constraints set by mindfsetnlc2() 1 function value has converged within epsf 2 sampling radius decreased below epsx 5 MaxIts steps was taken 7 stopping conditions are too stringent, further improvement is impossible, X contains best point found so far. 8 User requested termination via mindfrequesttermination() TIMERS Starting from ALGLIB 4.04, many optimizers report time spent in in the solver itself and in user callbacks. The time is reported in seconds, using floating-point (i.e. fractional-length intervals can be reported). In order to activate timers, the caller has to call mindfusetimers() function. The accuracy of the reported value depends on the specific programming language and OS being used: * C++, no AE_OS is #defined - the accuracy is that of time() function, i.e. one second. * C++, AE_OS=AE_WINDOWS is #defined - the accuracy is that of GetTickCount(), i.e. about 10-20ms * C++, AE_OS=AE_POSIX is #defined - the accuracy is that of gettimeofday() * C#, managed core, any OS - the accuracy is that of Environment.TickCount * C#, HPC core, any OS - the accuracy is that of a corresponding C++ version * any other language - the accuracy is that of a corresponding C++ version Whilst modern operating systems provide more accurate timers, these timers often have significant overhead or backward compatibility issues. Thus, ALGLIB stick to the most basic and efficient functions, even at the cost of some accuracy being lost. *************************************************************************/class mindfreport { public: mindfreport(); mindfreport(const mindfreport &rhs); mindfreport& operator=(const mindfreport &rhs); virtual ~mindfreport(); double f; ae_int_t iterationscount; ae_int_t nfev; double bcerr; double lcerr; double nlcerr; ae_int_t terminationtype; double timetotal; double timesolver; double timecallback; };
mindfstate class/************************************************************************* This object stores nonlinear optimizer state. You should use functions provided by MinDF subpackage to work with this object *************************************************************************/class mindfstate { public: mindfstate(); mindfstate(const mindfstate &rhs); mindfstate& operator=(const mindfstate &rhs); virtual ~mindfstate(); };
mindfcreate function/************************************************************************* GLOBAL OPTIMIZATION SUBJECT TO BOX/LINEAR/NONLINEAR CONSTRAINTS The subroutine minimizes function F(x) of N arguments subject to any combination of: * bound constraints * linear inequality constraints * linear equality constraints * nonlinear generalized inequality constraints Li<=Ci(x)<=Ui, with one of Li/Ui possibly being infinite REQUIREMENTS: * F() and C() do NOT have to be differentiable, locally Lipschitz or continuous. Most solvers in this subpackage can deal with nonsmoothness or minor discontinuities, although obviously smoother problems are the most easy ones. * generally, F() and C() must be computable at any point which is feasible subject to box constraints USAGE: 1. User initializes algorithm state with mindfcreate() call and chooses specific solver to be used. There is some solver which is used by default, with default settings, but you should NOT rely on the default choice. It may change in the future releases of ALGLIB without notice, and no one can guarantee that the new solver will be able to solve your problem with default settings. 2. User adds boundary and/or linear and/or nonlinear constraints by means of calling one of the following functions: a) mindfsetbc() for boundary constraints b) mindfsetlc2dense() for linear constraints c) mindfsetnlc2() for nonlinear constraints You may combine (a), (b) and (c) in one optimization problem. 3. User sets scale of the variables with mindfsetscale() function. It is VERY important to set variable scales because many derivative-free algorithms refuse to work when variables are badly scaled. Scaling helps to seed initial population, control convergence and enforce penalties for constraint violation. 4. Finally, user calls mindfoptimize() function which takes algorithm state and pointer (delegate, etc) to callback function which calculates F and G. 5. User calls mindfresults() to get a solution INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of X are used * if not given, automatically determined from size of X X - starting point, array[N]. Some solvers can utilize a good initial point to seed computations. As of ALGLIB 4.04, the initial point is: * used by GDEMO If the chosen solver does not need initial point, one can supply zeros. OUTPUT PARAMETERS: State - structure stores algorithm state IMPORTANT: the MINDF optimizer supports parallel model evaluation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions, greatly accelerates algorithms like differential evolution which usually issue batch requests to user callbacks which can be efficiently parallelized. Callback parallelism is usually beneficial when the batch evalution requires more than several milliseconds. See ALGLIB Reference Manual, 'Working with commercial version' section, and comments on mindfoptimize() function for more information. -- ALGLIB -- Copyright 24.07.2023 by Bochkanov Sergey *************************************************************************/void mindfcreate(const ae_int_t n, const real_1d_array &x, mindfstate &state, const xparams _xparams = alglib::xdefault); void mindfcreate(const real_1d_array &x, mindfstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
mindfiteration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool mindfiteration(mindfstate &state, const xparams _xparams = alglib::xdefault);
mindfoptimize function/************************************************************************* This family of functions is used to start iterations of nonlinear optimizer These functions accept following parameters: state - algorithm state fvec - callback which calculates function vector fi[] at given point x rep - optional callback which is called after each iteration can be NULL ptr - optional pointer which is passed to func/grad/hess/jac/rep can be NULL CALLBACK PARALLELISM The MINDF optimizer supports parallel model evaluation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions, greatly accelerates optimization when using a solver which issues batch requests, i.e. multiple requests for target values, which can be computed independently by different threads. Callback parallelism is usually beneficial when processing a batch request requires more than several milliseconds. It also requires the solver which issues requests in convenient batches, e.g. the differential evolution solver. See ALGLIB Reference Manual, 'Working with commercial version' section for more information. -- ALGLIB -- Copyright 25.07.2023 by Bochkanov Sergey *************************************************************************/void mindfoptimize(mindfstate &state, void (*fvec)(const real_1d_array &x, real_1d_array &fi, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault);
Examples: [1]
mindfrequesttermination function/************************************************************************* This subroutine submits request for termination of a running optimizer. It should be called from a user-supplied callback when user decides that it is time to "smoothly" terminate optimization process. As a result, the optimizer stops at the point which was "current accepted" when the termination request was submitted and returns error code 8 (successful termination). INPUT PARAMETERS: State - optimizer structure NOTE: after request for termination optimizer may perform several additional calls to user-supplied callbacks. It does NOT guarantee to stop immediately - it just guarantees that these additional calls will be discarded later. NOTE: calling this function on an optimizer which is NOT running will have no effect. NOTE: multiple calls to this function are possible. First call is counted, subsequent calls are silently ignored. -- ALGLIB -- Copyright 25.07.2023 by Bochkanov Sergey *************************************************************************/void mindfrequesttermination(mindfstate &state, const xparams _xparams = alglib::xdefault);
mindfresults function/************************************************************************* MinDF results INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: X - array[0..N-1], solution Rep - optimization report: rep.f stores objective value at the solution You should check rep.terminationtype in order to distinguish successful termination from unsuccessful one: * -8 internal integrity control detected infinite or NAN values in function/gradient. Abnormal termination signalled. * -3 box constraints are inconsistent * -1 inconsistent parameters were passed: * penalty parameter is zero, but we have nonlinear constraints set by MinDFsetnlc2() * 1 successful termination according to a solver-specific set of conditions * 8 User requested termination via minnsrequesttermination() If you activated timers with mindfusetimers(), you can also find out how much time was spent in various code parts: * rep.timetotal - for a total time in seconds * rep.timesolver - for a time spent in the solver itself * rep.timecallback - for a time spent in user callbacks See comments on mindfreport structure for more information about timers and their accuracy. -- ALGLIB -- Copyright 25.07.2023 by Bochkanov Sergey *************************************************************************/void mindfresults(const mindfstate &state, real_1d_array &x, mindfreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
mindfresultsbuf function/************************************************************************* Buffered implementation of MinDFresults() which uses pre-allocated buffer to store X[]. If buffer size is too small, it resizes buffer. It is intended to be used in the inner cycles of performance critical algorithms where array reallocation penalty is too large to be ignored. -- ALGLIB -- Copyright 25.07.2023 by Bochkanov Sergey *************************************************************************/void mindfresultsbuf(const mindfstate &state, real_1d_array &x, mindfreport &rep, const xparams _xparams = alglib::xdefault);
mindfsetalgogdemo function/************************************************************************* This subroutine sets optimization algorithm to the differential evolution solver GDEMO (Generalized Differential Evolution Multiobjective) with an automatic parameters selection. NOTE: a version with manually tuned parameters can be activated by calling the mindfsetalgogdemofixed() function. The primary stopping condition for the solver is to stop after the specified number of iterations. You can also specify additional criteria to stop early: * stop when subpopulation target values (2N+1 best individuals) are within EPS from the best one so far (function values seem to converge) * stop when both subpopulation target values AND subpopulation variable values are within EPS from the best one so far The first condition is specified with mindfsetcondf(), the second one is activated with mindfsetcondfx(). Both conditions are heuristics which may fail. Being 'within EPS from the best value so far' in practice means that we are somewhere within [0.1EPS,10EPS] from the true solution; however, on difficult problems this condition may fire too early. Imposing an additional requirement that variable values have clustered too may prevent us from premature stopping. However, on multi-extremal and/or noisy problems too many individuals may be trapped away from the optimum, preventing this condition from activation. ALGORITHM PROPERTIES: * the solver uses a variant of the adaptive parameter tuning strategy called 'Success-History Based Parameter Adaptation for Differential Evolution Ensemble' (SHADE) by Ryoji Tanabe and Alex Fukunaga. You do not have to specify crossover probability and differential weight, the solver will automatically choose the most appropriate strategy. * the solver can handle box, linear, nonlinear constraints. Linear and nonlinear constraints are handled by means of an L1/L2 penalty. The solver does not violate box constraints at any point, but may violate linear and nonlinear ones. Penalty coefficient can be changed with the mindfsetgdemopenalty() function. * the solver heavily depends on variable scales being available (specified by means of mindfsetscale() call) and on box constraints with both lower and upper bounds being available which are used to determine the search region. It will work without box constraints and without scales, but results are likely to be suboptimal. * the solver is SIMD-optimized and parallelized (in commercial ALGLIB editions), with nearly linear scalability of parallel processing. * this solver is intended for finding solutions with up to several digits of precision at best. Its primary purpose is to find at least some solution to an otherwise intractable problem. IMPORTANT: derivative-free optimization is inherently less robust than the smooth nonlinear programming, especially when nonsmoothness and discontinuities are present. Derivative-free algorithms have less convergence guarantees than their smooth counterparts. It is considered a normal (although, obviously, undesirable) situation when a derivative- -free algorithm fails to converge with desired precision. Having 2 digits of accurasy is already a good result, on difficult problems (high numerical noise, discontinuities) you may have even less than that. INPUT PARAMETERS: State - solver EpochsCnt - iterations count, >0. Usually the algorithm needs hundreds of iterations to converge. PopSize - population size, >=0. Zero value means that the default value (which is 10*N in the current version) will be chosen. Good values are in 5*N...20*N, with the smaller values being recommended for easy problems and the larger values for difficult multi-extremal and/or noisy tasks. -- ALGLIB -- Copyright 25.07.2023 by Bochkanov Sergey *************************************************************************/void mindfsetalgogdemo(mindfstate &state, const ae_int_t epochscnt, const ae_int_t popsize, const xparams _xparams = alglib::xdefault); void mindfsetalgogdemo(mindfstate &state, const ae_int_t epochscnt, const xparams _xparams = alglib::xdefault);
Examples: [1]
mindfsetalgogdemofixed function/************************************************************************* This subroutine sets optimization algorithm to the differential evolution solver GDEMO (Generalized Differential Evolution Multiobjective) with the manual parameters selection. Unlike DE with an automatic parameters selection this function requires user to manually specify algorithm parameters. In the general case the full-auto GDEMO is better. However, it has to spend some time finding out properties of a problem being solved; furthermore, it is not allowed to try potentially dangerous values of parameters that lead to premature stopping. Manually tuning the solver to the specific problem at hand can get 2x-3x better running time. Aside from that, the algorithm is fully equivalent to automatic GDEMO, and we recommend you reading comments on mindfsetalgogdemo() for more information about algorithm properties and stopping criteria. INPUT PARAMETERS: State - solver EpochsCnt - iterations count, >0. Usually the algorithm needs hundreds of iterations to converge. Strategy - specific DE strategy to use: * 0 for DE/rand/1 * 1 for DE/best/2 * 2 for DE/current-to-best/1 CrossoverProb- crossover probability, 0<CrossoverProb<1 DifferentialWeight- weight, 0<DifferentialWeight<2 PopSize - population size, >=0. Zero value means that the default value (which is 10*N in the current version) will be chosen. Good values are in 5*N...20*N, with the smaller values being recommended for easy problems and the larger values for difficult multi-extremal and/or noisy tasks. -- ALGLIB -- Copyright 25.07.2023 by Bochkanov Sergey *************************************************************************/void mindfsetalgogdemofixed(mindfstate &state, const ae_int_t epochscnt, const ae_int_t strategy, const double crossoverprob, const double differentialweight, const ae_int_t popsize, const xparams _xparams = alglib::xdefault);
Examples: [1]
mindfsetbc function/************************************************************************* This function sets box constraints. Box constraints are inactive by default (after initial creation). INPUT PARAMETERS: State - structure stores algorithm state BndL - lower bounds, array[N]. If some (all) variables are unbounded, you may specify very small number or -INF. BndU - upper bounds, array[N]. If some (all) variables are unbounded, you may specify very large number or +INF. -- ALGLIB -- Copyright 24.07.2023 by Bochkanov Sergey *************************************************************************/void mindfsetbc(mindfstate &state, const real_1d_array &bndl, const real_1d_array &bndu, const xparams _xparams = alglib::xdefault);
mindfsetcondf function/************************************************************************* This function sets stopping condition for the optimizer: function values has converged to a neighborhood whose size is proportional to epsF. Most derivarive-free solvers are heuristics, so the code used to implement this stopping condition is an heuristic too. Usually 'proportional to EPS' means that we are somewhere between Eps/10...Eps*10 away from the solution. However, there are no warranties that the solver has actually converged to something, although in practice it works well. The specific meaning of 'converging' is algorithm-dependent. It is possible that some future ALGLIB optimizers will ignore this condition, see comments on specific solvers for more info. This condition does not work for multi-objective problems. INPUT PARAMETERS: State - structure which stores algorithm state EpsF - >=0: * zero value means no condition for F * EpsF>0 means stopping when the solver converged with an error estimate less than EpsF*max(|F|,1) -- ALGLIB -- Copyright 23.04.2024 by Bochkanov Sergey *************************************************************************/void mindfsetcondf(mindfstate &state, const double epsf, const xparams _xparams = alglib::xdefault);
mindfsetcondfx function/************************************************************************* This function sets stopping conditions for the optimizer. This function sets a combined stopping condition: stopping when two criteria are met simultaneously: * function values has converged to a neighborhood whose size is proportional to epsF * variable values has converged to a neighborhood whose size is proportional to epsX It is possible to use only one condition by setting another EPS to zero. Most derivarive-free solvers are heuristics, so the code used to implement this stopping condition is an heuristic too. Usually 'proportional to EPS' means that we are somewhere between Eps/10...Eps*10 away from the solution. However, there are no warranties that the solver has actually converged to something, although in practice it works well. The specific meaning of 'converging' is algorithm-dependent. It is possible that some future ALGLIB optimizers will ignore this condition, see comments on specific solvers for more info. This condition does not work for multi-objective problems. INPUT PARAMETERS: State - structure which stores algorithm state EpsF - >=0: * zero value means no condition for F * EpsF>0 means stopping when the solver converged with an error estimate less than EpsF*max(|F|,1) EpsX - >=0: * zero value means no condition for X * EpsX>0 means stopping when the solver converged with error in I-th variable less than EpsX*S[i], where S[i] is a variable scale -- ALGLIB -- Copyright 23.04.2024 by Bochkanov Sergey *************************************************************************/void mindfsetcondfx(mindfstate &state, const double epsf, const double epsx, const xparams _xparams = alglib::xdefault);
mindfsetgdemopenalty function/************************************************************************* This subroutine tells GDEMO differential evolution optimizer to handle linear/nonlinear constraints by an L1/L2 penalty function. IMPORTANT: this function does NOT change the optimization algorithm. If want to activate differential evolution solver, you still have to call a proper mindfsetalgo???() function. INPUT PARAMETERS: State - solver Rho1, Rho2 - penalty parameters for constraint violations: * Rho1 is a multiplier for L1 penalty * Rho2 is a multiplier for L2 penalty * Rho1,Rho2>=0 * having both of them at zero means that some default value will be chosen. Ignored for problems with box-only constraints. L1 penalty is usually better at enforcing constraints, but leads to slower convergence than L2 penalty. It is possible to combine both kinds of penalties together. There is a compromise between constraint satisfaction and optimality: high values of Rho mean that constraints are satisfied with high accuracy but that the target may be underoptimized due to numerical difficulties. Small values of Rho mean that the solution may grossly violate constraints. Choosing good Rho is usually a matter of trial and error. -- ALGLIB -- Copyright 25.07.2023 by Bochkanov Sergey *************************************************************************/void mindfsetgdemopenalty(mindfstate &state, const double rho1, const double rho2, const xparams _xparams = alglib::xdefault);
Examples: [1]
mindfsetgdemoprofilequick function/************************************************************************* This subroutine tells GDEMO differential evolution optimizer to use a QUICK profile. The QUICK profile is intended to facilitate accelerated convergence on medium-complexity problems at the cost of (sometimes) having premature convergence on difficult and/or multi-extremal problems. The ROBUST profile can be selected if you favor convergence warranties over speed. In most cases, the ROBUST profile is ~2x-3x slower than the QUICK one. This function has effect only on adaptive GDEMO with automatic parameters selection. It has no effect on fixed-parameters GDEMO or any other solvers. IMPORTANT: this function does NOT change the optimization algorithm. If you want to activate differential evolution solver, you still have to call a proper mindfsetalgo???() function. INPUT PARAMETERS: State - solver -- ALGLIB -- Copyright 25.04.2024 by Bochkanov Sergey *************************************************************************/void mindfsetgdemoprofilequick(mindfstate &state, const xparams _xparams = alglib::xdefault);
mindfsetgdemoprofilerobust function/************************************************************************* This subroutine tells GDEMO differential evolution optimizer to use a ROBUST profile (the default option). The ROBUST profile is intended to facilitate explorative behavior and robust convergence even on difficult multi-extremal problems. It comes at the expense of increased running time even on easy problems. The QUICK profile can be chosen if your problem is relatively easy to handle and you prefer speed over robustness. In most cases, the QUICK profile is ~2x-3x faster than the robust one. This function has effect only on adaptive GDEMO with automatic parameters selection. It has no effect on fixed-parameters GDEMO or any other solvers. IMPORTANT: this function does NOT change the optimization algorithm. If want to activate differential evolution solver, you still have to call a proper mindfsetalgo???() function. INPUT PARAMETERS: State - solver -- ALGLIB -- Copyright 25.04.2024 by Bochkanov Sergey *************************************************************************/void mindfsetgdemoprofilerobust(mindfstate &state, const xparams _xparams = alglib::xdefault);
mindfsetlc2dense function/************************************************************************* This function sets two-sided linear constraints AL <= A*x <= AU with dense constraint matrix A. INPUT PARAMETERS: State - structure previously allocated with MinDFcreate() call. A - linear constraints, array[K,N]. Each row of A represents one constraint. One-sided inequality constraints, two- sided inequality constraints, equality constraints are supported (see below) AL, AU - lower and upper bounds, array[K]; * AL[i]=AU[i] => equality constraint Ai*x * AL[i]<AU[i] => two-sided constraint AL[i]<=Ai*x<=AU[i] * AL[i]=-INF => one-sided constraint Ai*x<=AU[i] * AU[i]=+INF => one-sided constraint AL[i]<=Ai*x * AL[i]=-INF, AU[i]=+INF => constraint is ignored K - number of equality/inequality constraints, K>=0; if not given, inferred from sizes of A, AL, AU. -- ALGLIB -- Copyright 25.07.2023 by Bochkanov Sergey *************************************************************************/void mindfsetlc2dense(mindfstate &state, const real_2d_array &a, const real_1d_array &al, const real_1d_array &au, const ae_int_t k, const xparams _xparams = alglib::xdefault); void mindfsetlc2dense(mindfstate &state, const real_2d_array &a, const real_1d_array &al, const real_1d_array &au, const xparams _xparams = alglib::xdefault);
Examples: [1]
mindfsetnlc2 function/************************************************************************* This function sets two-sided nonlinear constraints. In fact, this function sets only NUMBER of the nonlinear constraints. Constraints themselves (constraint functions) are passed to the MinDFOptimize() method. This method accepts user-defined vector function F[] where: * first component of F[] corresponds to the objective * subsequent NNLC components of F[] correspond to the two-sided nonlinear constraints NL<=C(x)<=NU, where * NL[i]=NU[i] => I-th row is an equality constraint Ci(x)=NL * NL[i]<NU[i] => I-th tow is a two-sided constraint NL[i]<=Ci(x)<=NU[i] * NL[i]=-INF => I-th row is an one-sided constraint Ci(x)<=NU[i] * NU[i]=+INF => I-th row is an one-sided constraint NL[i]<=Ci(x) * NL[i]=-INF, NU[i]=+INF => constraint is ignored NOTE: you may combine nonlinear constraints with linear/boundary ones. If your problem has mixed constraints, you may explicitly specify some of them as linear or box ones. It helps optimizer to handle them more efficiently. INPUT PARAMETERS: State - structure previously allocated with MinDFCreate call. NL - array[NNLC], lower bounds, can contain -INF NU - array[NNLC], lower bounds, can contain +INF NNLC - constraints count, NNLC>=0 NOTE 1: nonlinear constraints are satisfied only approximately! It is possible that algorithm will evaluate function outside of feasible area! NOTE 2: the algorithm scales variables according to the scale specified by MinDFSetScale() function, so it can handle problems with badly scaled variables (as long as we KNOW their scales). However, there is no way to automatically scale nonlinear constraints. Inappropriate scaling of nonlinear constraints may ruin convergence. Solving problem with constraint "1000*G0(x)=0" is NOT the same as solving it with constraint "0.001*G0(x)=0". It means that YOU are the one who is responsible for the correct scaling of the nonlinear constraints. We recommend you to scale nonlinear constraints in such a way that the derivatives (if constraints are differentiable) have approximately unit magnitude (for problems with unit variable scales) or have magnitudes approximately equal to 1/S[i] (where S is a variable scale set by MinDFSetScale() function). -- ALGLIB -- Copyright 25.07.2023 by Bochkanov Sergey *************************************************************************/void mindfsetnlc2(mindfstate &state, const real_1d_array &nl, const real_1d_array &nu, const ae_int_t nnlc, const xparams _xparams = alglib::xdefault); void mindfsetnlc2(mindfstate &state, const real_1d_array &nl, const real_1d_array &nu, const xparams _xparams = alglib::xdefault);
Examples: [1]
mindfsetscale function/************************************************************************* This function sets variable scales. ALGLIB optimizers use scaling matrices to test stopping conditions (step size and gradient are scaled before comparison with tolerances) and to guide algorithm steps. The scale of a variable is a translation invariant measure of: a) "how large" the variable is b) how large the step should be to make significant changes in the function INPUT PARAMETERS: State - structure stores algorithm state S - array[N], non-zero scaling coefficients S[i] may be negative, sign doesn't matter. -- ALGLIB -- Copyright 25.07.2023 by Bochkanov Sergey *************************************************************************/void mindfsetscale(mindfstate &state, const real_1d_array &s, const xparams _xparams = alglib::xdefault);
Examples: [1]
mindfsetseed function/************************************************************************* This function sets seed used by internal RNG. By default, a random seed is used, i.e. every time you run the solver, we seed its generator with a new value obtained from the system-wide RNG. Thus, the solver returns non-deterministic results. You can change such a behavior by specifying a fixed positive seed value. INPUT PARAMETERS: S - optimizer structure SeedVal - seed value: * positive values are used for seeding RNG with a fixed seed, i.e. subsequent runs on the same objective will return the same results * non-positive seed means that a random seed is used for every run, i.e. subsequent runs on the same objective will return slightly different results -- ALGLIB -- Copyright 26.04.2024 by Bochkanov Sergey *************************************************************************/void mindfsetseed(mindfstate &s, const ae_int_t seedval, const xparams _xparams = alglib::xdefault);
mindfsetxrep function/************************************************************************* This function turns on/off reporting. INPUT PARAMETERS: State - structure which stores algorithm state NeedXRep- whether iteration reports are needed or not If NeedXRep is True, algorithm will call rep() callback function if it is provided to MinDFOptimize(). NOTE: algorithm passes two parameters to rep() callback - the best point so far and a function value at the point. For unconstrained problems the function value is non-increasing (the most recent best point is always at least not worse than the previous best one). However, it can increase between iterations when solving constrained problems (a better point may have higher objective value but smaller constraint violation). -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void mindfsetxrep(mindfstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
mindfusetimers function/************************************************************************* This function activates/deactivates internal timers used to track time spent in various parts of the solver (mostly, callbacks vs solver itself). When activated with this function, the following timings are stored in the mindfreport structure fields: * total time spend in the optimization * time spent in the callback * time spent in the solver itself See comments on mindfreport structure for more information about timers and their accuracy. Timers are an essential part of reports that helps to find out where the most time is spent and how to optimize the code. E.g., noticing that significant amount of time is spent in numerical differentiation makes obvious that ALGLIB-provided parallel numerical differentiation is needed. However, time measurements add noticeable overhead, about 50-100ns per function call. In some applications it results in a significant slowdown, that's why this option is inactive by default and should be manually activated. INPUT PARAMETERS: State - structure which stores algorithm state UseTimers- true or false NOTE: when tracing is turned on with alglib::trace_file(), some derivative free solvers may also perform internal, more detailed time measurements, which are printed to the log file. -- ALGLIB -- Copyright 23.04.2024 by Bochkanov Sergey *************************************************************************/void mindfusetimers(mindfstate &state, const bool usetimers, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void nlcfunc2_fvec(const real_1d_array &x, real_1d_array &fi, void *ptr)
{
//
// this callback calculates
//
// f0(x0,x1,x2) = x0+x1
// f1(x0,x1,x2) = x2-exp(x0)
// f2(x0,x1,x2) = x0^2+x1^2-1
//
fi[0] = x[0]+x[1];
fi[1] = x[2]-exp(x[0]);
fi[2] = x[0]*x[0] + x[1]*x[1] - 1.0;
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of
//
// f(x0,x1) = x0+x1
//
// subject to nonlinear constraints
//
// x0^2 + x1^2 - 1 <= 0
// x2-exp(x0) = 0
//
real_1d_array x0 = "[0,0,0]";
real_1d_array s = "[1,1,1]";
mindfstate state;
mindfreport rep;
real_1d_array x1;
//
// Create optimizer object
//
mindfcreate(x0, state);
mindfsetscale(state, s);
//
// Choose one of the nonlinear programming solvers supported by MINDF
// optimizer.
//
// This example shows how to use GDEMO (Generalized Differential Evolution,
// MultiObjective) solver working in a single-objective mode. This solver
// uses an adaptive choice of DE parameters (crossover, weight and strategy),
// automatically choosing the most appropriate settings during the optimization.
//
// Thus, the only tunable parameters are:
// * iterations count
// * population size
// * algorithm profile (ROBUST or QUICK)
//
// The latter two parameters can be omitted, the solver will use a default
// population size (10*N in the current version) and a default profile (ROBUST
// one).
//
// Metaheuristics typically need hundreds or thousands of iterations to converge,
// in this example we set 200 iterations. Good values for population size
// are between 5*N and 20*N, with 5*N being recommended for easy problems
// and 20*N (or more) being recommended for difficult problems with multiple
// extrema, many cross-interacting variables and/or noise.
//
// In addition to these parameters it is also possible to specify a so-called
// 'profile' - a set of recommendations regarding decisions algorithm is allowed
// to make during parameters autotuning:
// * the ROBUST profile is a default option. The solver tries only conservative
// strategies that have low probability of a failure (stagnation far away
// from the solution)
// * the QUICK profile is intended to facilitate accelerated convergence on
// medium-complexity problems at the cost of (sometimes) having premature
// convergence on difficult multi-extremal problems. It most often results
// in a 2x-3x higher convergence speed than the ROBUST profile.
//
// In this simple example we do not provide variable bounds and scales; however,
// on real life problems it is very important to box as many variables as possible
// (it helps to generate initial population and to avoid bad parameter values)
// and to provide variable scales. Differential Evolution itself is scale-invariant;
// however, penalties for constraint violation are scale-dependent.
//
ae_int_t maxits = 200;
mindfsetalgogdemo(state, maxits);
mindfsetgdemoprofilerobust(state);
//
// Unlike smooth solvers, metaheuristics do not have well-defined stopping criteria.
// It is recommended to run the solver until iterations budget is exhausted.
//
// However, it is possible to let the solver stop early, when either:
// * subpopulation target values (2N+1 best individuals) are within
// EPS from the best one so far (function values seem to converge)
// * or 2N+1-subpopulation target values AND variable values are within EPS from
// the best solution so far
//
// Both conditions are heuristics that may fail. The fact that many candidate
// objective values have clustered within EPS of the best objective value so far
// usually means that we are somewhere within [0.1EPS,10EPS] away from the true
// solution; however, on difficult problems this condition may fire too early.
//
// Imposing an additional requirement that variable values have clustered too
// may prevent us from premature stopping. However, on multi-extremal and/or
// noisy problems too many individuals may be trapped away from the optimum,
// preventing this condition from activation.
//
// The summary is that stopping criteria are heavily problem-dependent.
//
mindfsetcondf(state, 0.00001);
//
// Set nonlinear constraints.
//
// ALGLIB supports any combination of box, linear and nonlinear
// constraints. This specific example uses only nonlinear ones.
//
// Since version 4.01, ALGLIB supports the most general form of
// nonlinear constraints: two-sided constraints NL<=C(x)<=NU, with
// elements being possibly infinite (means that this specific bound is
// ignored). It includes equality constraints, upper/lower inequality
// constraints, range constraints. In particular, a pair of constraints
//
// x2-exp(x0) = 0
// x0^2 + x1^2 - 1 <= 0
//
// can be specified by passing NL=[0,-INF], NU=[0,0] to mindfsetnlc2().
// Constraining functions themselves are passed as a part of a problem
// target vector (see below).
//
//
// Unlike smooth optimizers like SQP which naturally include linear and
// nonlinear constraints into the algorithm, derivative-free methods
// often need special strategies to deal with them, with each strategy
// having its own limitations:
//
// * an L2 penalty, which has good global constraint enforcement
// properties, but usually allows some moderate constraint violation
//
// * an L1 penalty, which has potential to enforce constraints exactly,
// but has somewhat weaker ability to move iterations from far away
// points closer to the feasible area. It also has somewhat harder
// numerical properties, needing more iterations to converge.
//
// * a combined L1/L2 penalty, which is a good compromise
//
// The code below sets constraints bounds and tells the solver to use
// a mixed L1/L2 penalized strategy.
//
// NOTE: box constraints require no special handling.
//
real_1d_array nl = "[0,-inf]";
real_1d_array nu = "[0,0]";
double rho1 = 5;
double rho2 = 5;
mindfsetnlc2(state, nl, nu);
mindfsetgdemopenalty(state, rho1, rho2);
//
// Optimize and test results.
//
// The optimizer object accepts vector function with its first component
// being a target and subsequent components being nonlinear constraints.
//
// So, our vector function has the following form
//
// {f0,f1,f2} = { x0+x1 , x2-exp(x0) , x0^2+x1^2-1 }
//
// with f0 being target function, f1 being equality constraint "f1=0",
// f2 being inequality constraint "f2<=0".
//
//
//
// The commercial ALGLIB has two important improvements over the free edition:
// * callback parallelism
// * SIMD kernels for candidate points generation
//
// Differential evolution evaluates objectives/constraints in large batches.
// When the batch takes more than several milliseconds to process, it makes
// sense to compute function values at different points in parallel. It is
// called 'callback parallelism'.
//
// Another useful performance improvement is an ability to utilize SIMD for
// massive random numbers generation and mutation/crossover. The performance
// impact of these operations can be noticeable when solving problems with
// cheap objectives.
//
alglib::mindfoptimize(state, nlcfunc2_fvec);
mindfresults(state, x1, rep);
printf("%s\n", x1.tostring(2).c_str()); // EXPECTED: [-0.70710,-0.70710,0.49306]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
minlbfgs subpackage| minlbfgs_d_1 | Nonlinear optimization by L-BFGS | |
| minlbfgs_d_2 | Nonlinear optimization with additional settings and restarts | |
| minlbfgs_numdiff | Nonlinear optimization by L-BFGS with numerical differentiation |
minlbfgsreport class/************************************************************************* This structure stores optimization report: * IterationsCount total number of inner iterations * NFEV number of gradient evaluations * TerminationType termination type (see below) TERMINATION CODES TerminationType field contains completion code, which can be: -8 internal integrity control detected infinite or NAN values in function/gradient. Abnormal termination signalled. 1 relative function improvement is no more than EpsF. 2 relative step is no more than EpsX. 4 gradient norm is no more than EpsG 5 MaxIts steps was taken 7 stopping conditions are too stringent, further improvement is impossible, X contains best point found so far. 8 terminated by user who called minlbfgsrequesttermination(). X contains point which was "current accepted" when termination request was submitted. Other fields of this structure are not documented and should not be used! *************************************************************************/class minlbfgsreport { public: minlbfgsreport(); minlbfgsreport(const minlbfgsreport &rhs); minlbfgsreport& operator=(const minlbfgsreport &rhs); virtual ~minlbfgsreport(); ae_int_t iterationscount; ae_int_t nfev; ae_int_t terminationtype; };
minlbfgsstate class/************************************************************************* *************************************************************************/class minlbfgsstate { public: minlbfgsstate(); minlbfgsstate(const minlbfgsstate &rhs); minlbfgsstate& operator=(const minlbfgsstate &rhs); virtual ~minlbfgsstate(); };
minlbfgscreate function/************************************************************************* LIMITED MEMORY BFGS METHOD FOR LARGE SCALE OPTIMIZATION DESCRIPTION: The subroutine minimizes function F(x) of N arguments by using a quasi- Newton method (LBFGS scheme) which is optimized to use a minimum amount of memory. The subroutine generates the approximation of an inverse Hessian matrix by using information about the last M steps of the algorithm (instead of N). It lessens a required amount of memory from a value of order N^2 to a value of order 2*N*M. REQUIREMENTS: Algorithm will request following information during its operation: * function value F and its gradient G (simultaneously) at given point X USAGE: 1. User initializes algorithm state with MinLBFGSCreate() call 2. User tunes solver parameters with MinLBFGSSetCond() MinLBFGSSetStpMax() and other functions 3. User calls MinLBFGSOptimize() function which takes algorithm state and pointer (delegate, etc.) to callback function which calculates F/G. 4. User calls MinLBFGSResults() to get solution 5. Optionally user may call MinLBFGSRestartFrom() to solve another problem with same N/M but another starting point and/or another function. MinLBFGSRestartFrom() allows to reuse already initialized structure. INPUT PARAMETERS: N - problem dimension. N>0 M - number of corrections in the BFGS scheme of Hessian approximation update. Recommended value: 3<=M<=7. The smaller value causes worse convergence, the bigger will not cause a considerably better convergence, but will cause a fall in the performance. M<=N. X - initial solution approximation, array[0..N-1]. OUTPUT PARAMETERS: State - structure which stores algorithm state IMPORTANT: the LBFGS optimizer supports parallel parallel numerical differentiation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions greatly accelerates optimization with numerical differentiation of an expensive target functions. Callback parallelism is usually beneficial when computing a numerical gradient requires more than several milliseconds. See ALGLIB Reference Manual, 'Working with commercial version' section, and comments on minlbfgsoptimize() function for more information. NOTES: 1. you may tune stopping conditions with MinLBFGSSetCond() function 2. if target function contains exp() or other fast growing functions, and optimization algorithm makes too large steps which leads to overflow, use MinLBFGSSetStpMax() function to bound algorithm's steps. However, L-BFGS rarely needs such a tuning. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minlbfgscreate(const ae_int_t n, const ae_int_t m, const real_1d_array &x, minlbfgsstate &state, const xparams _xparams = alglib::xdefault); void minlbfgscreate(const ae_int_t m, const real_1d_array &x, minlbfgsstate &state, const xparams _xparams = alglib::xdefault);
minlbfgscreatef function/************************************************************************* The subroutine is finite difference variant of MinLBFGSCreate(). It uses finite differences in order to differentiate target function. Description below contains information which is specific to this function only. We recommend to read comments on MinLBFGSCreate() in order to get more information about creation of LBFGS optimizer. INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of X are used * if not given, automatically determined from size of X M - number of corrections in the BFGS scheme of Hessian approximation update. Recommended value: 3<=M<=7. The smaller value causes worse convergence, the bigger will not cause a considerably better convergence, but will cause a fall in the performance. M<=N. X - starting point, array[0..N-1]. DiffStep- differentiation step, >0 OUTPUT PARAMETERS: State - structure which stores algorithm state IMPORTANT: the LBFGS optimizer supports parallel parallel numerical differentiation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions greatly accelerates optimization with numerical differentiation of an expensive target functions. Callback parallelism is usually beneficial when computing a numerical gradient requires more than several milliseconds. See ALGLIB Reference Manual, 'Working with commercial version' section, and comments on minlbfgsoptimize() function for more information. NOTES: 1. algorithm uses 4-point central formula for differentiation. 2. differentiation step along I-th axis is equal to DiffStep*S[I] where S[] is scaling vector which can be set by MinLBFGSSetScale() call. 3. we recommend you to use moderate values of differentiation step. Too large step will result in too large truncation errors, while too small step will result in too large numerical errors. 1.0E-6 can be good value to start with. 4. Numerical differentiation is very inefficient - one gradient calculation needs 4*N function evaluations. This function will work for any N - either small (1...10), moderate (10...100) or large (100...). However, performance penalty will be too severe for any N's except for small ones. We should also say that code which relies on numerical differentiation is less robust and precise. LBFGS needs exact gradient values. Imprecise gradient may slow down convergence, especially on highly nonlinear problems. Thus we recommend to use this function for fast prototyping on small- dimensional problems only, and to implement analytical gradient as soon as possible. -- ALGLIB -- Copyright 16.05.2011 by Bochkanov Sergey *************************************************************************/void minlbfgscreatef(const ae_int_t n, const ae_int_t m, const real_1d_array &x, const double diffstep, minlbfgsstate &state, const xparams _xparams = alglib::xdefault); void minlbfgscreatef(const ae_int_t m, const real_1d_array &x, const double diffstep, minlbfgsstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlbfgsiteration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool minlbfgsiteration(minlbfgsstate &state, const xparams _xparams = alglib::xdefault);
minlbfgsoptguardgradient function/************************************************************************* This function activates/deactivates verification of the user-supplied analytic gradient. Upon activation of this option OptGuard integrity checker performs numerical differentiation of your target function at the initial point (note: future versions may also perform check at the final point) and compares numerical gradient with analytic one provided by you. If difference is too large, an error flag is set and optimization session continues. After optimization session is over, you can retrieve the report which stores both gradients and specific components highlighted as suspicious by the OptGuard. The primary OptGuard report can be retrieved with minlbfgsoptguardresults(). IMPORTANT: gradient check is a high-overhead option which will cost you about 3*N additional function evaluations. In many cases it may cost as much as the rest of the optimization session. YOU SHOULD NOT USE IT IN THE PRODUCTION CODE UNLESS YOU WANT TO CHECK DERIVATIVES PROVIDED BY SOME THIRD PARTY. NOTE: unlike previous incarnation of the gradient checking code, OptGuard does NOT interrupt optimization even if it discovers bad gradient. INPUT PARAMETERS: State - structure used to store algorithm state TestStep - verification step used for numerical differentiation: * TestStep=0 turns verification off * TestStep>0 activates verification You should carefully choose TestStep. Value which is too large (so large that function behavior is non- cubic at this scale) will lead to false alarms. Too short step will result in rounding errors dominating numerical derivative. You may use different step for different parameters by means of setting scale with minlbfgssetscale(). === EXPLANATION ========================================================== In order to verify gradient algorithm performs following steps: * two trial steps are made to X[i]-TestStep*S[i] and X[i]+TestStep*S[i], where X[i] is i-th component of the initial point and S[i] is a scale of i-th parameter * F(X) is evaluated at these trial points * we perform one more evaluation in the middle point of the interval * we build cubic model using function values and derivatives at trial points and we compare its prediction with actual value in the middle point -- ALGLIB -- Copyright 15.06.2014 by Bochkanov Sergey *************************************************************************/void minlbfgsoptguardgradient(minlbfgsstate &state, const double teststep, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlbfgsoptguardnonc1test0results function/************************************************************************* Detailed results of the OptGuard integrity check for nonsmoothness test #0 Nonsmoothness (non-C1) test #0 studies function values (not gradient!) obtained during line searches and monitors behavior of the directional derivative estimate. This test is less powerful than test #1, but it does not depend on the gradient values and thus it is more robust against artifacts introduced by numerical differentiation. Two reports are returned: * a "strongest" one, corresponding to line search which had highest value of the nonsmoothness indicator * a "longest" one, corresponding to line search which had more function evaluations, and thus is more detailed In both cases following fields are returned: * positive - is TRUE when test flagged suspicious point; FALSE if test did not notice anything (in the latter cases fields below are empty). * x0[], d[] - arrays of length N which store initial point and direction for line search (d[] can be normalized, but does not have to) * stp[], f[] - arrays of length CNT which store step lengths and function values at these points; f[i] is evaluated in x0+stp[i]*d. * stpidxa, stpidxb - we suspect that function violates C1 continuity between steps #stpidxa and #stpidxb (usually we have stpidxb=stpidxa+3, with most likely position of the violation between stpidxa+1 and stpidxa+2. ========================================================================== = SHORTLY SPEAKING: build a 2D plot of (stp,f) and look at it - you will = see where C1 continuity is violated. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: strrep - C1 test #0 "strong" report lngrep - C1 test #0 "long" report -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minlbfgsoptguardnonc1test0results(const minlbfgsstate &state, optguardnonc1test0report &strrep, optguardnonc1test0report &lngrep, const xparams _xparams = alglib::xdefault);
minlbfgsoptguardnonc1test1results function/************************************************************************* Detailed results of the OptGuard integrity check for nonsmoothness test #1 Nonsmoothness (non-C1) test #1 studies individual components of the gradient computed during line search. When precise analytic gradient is provided this test is more powerful than test #0 which works with function values and ignores user-provided gradient. However, test #0 becomes more powerful when numerical differentiation is employed (in such cases test #1 detects higher levels of numerical noise and becomes too conservative). This test also tells specific components of the gradient which violate C1 continuity, which makes it more informative than #0, which just tells that continuity is violated. Two reports are returned: * a "strongest" one, corresponding to line search which had highest value of the nonsmoothness indicator * a "longest" one, corresponding to line search which had more function evaluations, and thus is more detailed In both cases following fields are returned: * positive - is TRUE when test flagged suspicious point; FALSE if test did not notice anything (in the latter cases fields below are empty). * vidx - is an index of the variable in [0,N) with nonsmooth derivative * x0[], d[] - arrays of length N which store initial point and direction for line search (d[] can be normalized, but does not have to) * stp[], g[] - arrays of length CNT which store step lengths and gradient values at these points; g[i] is evaluated in x0+stp[i]*d and contains vidx-th component of the gradient. * stpidxa, stpidxb - we suspect that function violates C1 continuity between steps #stpidxa and #stpidxb (usually we have stpidxb=stpidxa+3, with most likely position of the violation between stpidxa+1 and stpidxa+2. ========================================================================== = SHORTLY SPEAKING: build a 2D plot of (stp,f) and look at it - you will = see where C1 continuity is violated. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: strrep - C1 test #1 "strong" report lngrep - C1 test #1 "long" report -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minlbfgsoptguardnonc1test1results(minlbfgsstate &state, optguardnonc1test1report &strrep, optguardnonc1test1report &lngrep, const xparams _xparams = alglib::xdefault);
minlbfgsoptguardresults function/************************************************************************* Results of OptGuard integrity check, should be called after optimization session is over. === PRIMARY REPORT ======================================================= OptGuard performs several checks which are intended to catch common errors in the implementation of nonlinear function/gradient: * incorrect analytic gradient * discontinuous (non-C0) target functions (constraints) * nonsmooth (non-C1) target functions (constraints) Each of these checks is activated with appropriate function: * minlbfgsoptguardgradient() for gradient verification * minlbfgsoptguardsmoothness() for C0/C1 checks Following flags are set when these errors are suspected: * rep.badgradsuspected, and additionally: * rep.badgradvidx for specific variable (gradient element) suspected * rep.badgradxbase, a point where gradient is tested * rep.badgraduser, user-provided gradient (stored as 2D matrix with single row in order to make report structure compatible with more complex optimizers like MinNLC or MinLM) * rep.badgradnum, reference gradient obtained via numerical differentiation (stored as 2D matrix with single row in order to make report structure compatible with more complex optimizers like MinNLC or MinLM) * rep.nonc0suspected * rep.nonc1suspected === ADDITIONAL REPORTS/LOGS ============================================== Several different tests are performed to catch C0/C1 errors, you can find out specific test signaled error by looking to: * rep.nonc0test0positive, for non-C0 test #0 * rep.nonc1test0positive, for non-C1 test #0 * rep.nonc1test1positive, for non-C1 test #1 Additional information (including line search logs) can be obtained by means of: * minlbfgsoptguardnonc1test0results() * minlbfgsoptguardnonc1test1results() which return detailed error reports, specific points where discontinuities were found, and so on. ========================================================================== INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: rep - generic OptGuard report; more detailed reports can be retrieved with other functions. NOTE: false negatives (nonsmooth problems are not identified as nonsmooth ones) are possible although unlikely. The reason is that you need to make several evaluations around nonsmoothness in order to accumulate enough information about function curvature. Say, if you start right from the nonsmooth point, optimizer simply won't get enough data to understand what is going wrong before it terminates due to abrupt changes in the derivative. It is also possible that "unlucky" step will move us to the termination too quickly. Our current approach is to have less than 0.1% false negatives in our test examples (measured with multiple restarts from random points), and to have exactly 0% false positives. -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minlbfgsoptguardresults(minlbfgsstate &state, optguardreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlbfgsoptguardsmoothness function/************************************************************************* This function activates/deactivates nonsmoothness monitoring option of the OptGuard integrity checker. Smoothness monitor silently observes solution process and tries to detect ill-posed problems, i.e. ones with: a) discontinuous target function (non-C0) b) nonsmooth target function (non-C1) Smoothness monitoring does NOT interrupt optimization even if it suspects that your problem is nonsmooth. It just sets corresponding flags in the OptGuard report which can be retrieved after optimization is over. Smoothness monitoring is a moderate overhead option which often adds less than 1% to the optimizer running time. Thus, you can use it even for large scale problems. NOTE: OptGuard does NOT guarantee that it will always detect C0/C1 continuity violations. First, minor errors are hard to catch - say, a 0.0001 difference in the model values at two sides of the gap may be due to discontinuity of the model - or simply because the model has changed. Second, C1-violations are especially difficult to detect in a noninvasive way. The optimizer usually performs very short steps near the nonsmoothness, and differentiation usually introduces a lot of numerical noise. It is hard to tell whether some tiny discontinuity in the slope is due to real nonsmoothness or just due to numerical noise alone. Our top priority was to avoid false positives, so in some rare cases minor errors may went unnoticed (however, in most cases they can be spotted with restart from different initial point). INPUT PARAMETERS: state - algorithm state level - monitoring level: * 0 - monitoring is disabled * 1 - noninvasive low-overhead monitoring; function values and/or gradients are recorded, but OptGuard does not try to perform additional evaluations in order to get more information about suspicious locations. === EXPLANATION ========================================================== One major source of headache during optimization is the possibility of the coding errors in the target function/constraints (or their gradients). Such errors most often manifest themselves as discontinuity or nonsmoothness of the target/constraints. Another frequent situation is when you try to optimize something involving lots of min() and max() operations, i.e. nonsmooth target. Although not a coding error, it is nonsmoothness anyway - and smooth optimizers usually stop right after encountering nonsmoothness, well before reaching solution. OptGuard integrity checker helps you to catch such situations: it monitors function values/gradients being passed to the optimizer and tries to errors. Upon discovering suspicious pair of points it raises appropriate flag (and allows you to continue optimization). When optimization is done, you can study OptGuard result. -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minlbfgsoptguardsmoothness(minlbfgsstate &state, const ae_int_t level, const xparams _xparams = alglib::xdefault); void minlbfgsoptguardsmoothness(minlbfgsstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlbfgsoptimize function/************************************************************************* This family of functions is used to start iterations of nonlinear optimizer These functions accept following parameters: state - algorithm state func - callback which calculates function (or merit function) value func at given point x grad - callback which calculates function (or merit function) value func and gradient grad at given point x rep - optional callback which is called after each iteration can be NULL ptr - optional pointer which is passed to func/grad/hess/jac/rep can be NULL CALLBACK PARALLELISM: The LBFGS optimizer supports parallel numerical differentiation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions, greatly accelerates numerical differentiation of expensive targets. Callback parallelism is usually beneficial computing a numerical gradient requires more than several milliseconds. In this case the job of computing individual gradient components can be split between multiple threads. Even inexpensive targets can benefit from parallelism, if you have many variables. ALGLIB Reference Manual, 'Working with commercial version' section, tells how to activate callback parallelism for your programming language. CALLBACKS ACCEPTED 1. This function has two different implementations: one which uses exact (analytical) user-supplied gradient, and one which uses function value only and numerically differentiates function in order to obtain gradient. Depending on the specific function used to create optimizer object (either MinLBFGSCreate() for analytical gradient or MinLBFGSCreateF() for numerical differentiation) you should choose appropriate variant of MinLBFGSOptimize() - one which accepts function AND gradient or one which accepts function ONLY. Be careful to choose variant of MinLBFGSOptimize() which corresponds to your optimization scheme! Table below lists different combinations of callback (function/gradient) passed to MinLBFGSOptimize() and specific function used to create optimizer. | USER PASSED TO MinLBFGSOptimize() CREATED WITH | function only | function and gradient ------------------------------------------------------------ MinLBFGSCreateF() | work FAIL MinLBFGSCreate() | FAIL work Here "FAIL" denotes inappropriate combinations of optimizer creation function and MinLBFGSOptimize() version. Attemps to use such combination (for example, to create optimizer with MinLBFGSCreateF() and to pass gradient information to MinCGOptimize()) will lead to exception being thrown. Either you did not pass gradient when it WAS needed or you passed gradient when it was NOT needed. -- ALGLIB -- Copyright 20.03.2009 by Bochkanov Sergey *************************************************************************/void minlbfgsoptimize(minlbfgsstate &state, void (*func)(const real_1d_array &x, double &func, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault); void minlbfgsoptimize(minlbfgsstate &state, void (*grad)(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault);
minlbfgsrequesttermination function/************************************************************************* This subroutine submits request for termination of running optimizer. It should be called from user-supplied callback when user decides that it is time to "smoothly" terminate optimization process. As result, optimizer stops at point which was "current accepted" when termination request was submitted and returns error code 8 (successful termination). INPUT PARAMETERS: State - optimizer structure NOTE: after request for termination optimizer may perform several additional calls to user-supplied callbacks. It does NOT guarantee to stop immediately - it just guarantees that these additional calls will be discarded later. NOTE: calling this function on optimizer which is NOT running will have no effect. NOTE: multiple calls to this function are possible. First call is counted, subsequent calls are silently ignored. -- ALGLIB -- Copyright 08.10.2014 by Bochkanov Sergey *************************************************************************/void minlbfgsrequesttermination(minlbfgsstate &state, const xparams _xparams = alglib::xdefault);
minlbfgsrestartfrom function/************************************************************************* This subroutine restarts LBFGS algorithm from new point. All optimization parameters are left unchanged. This function allows to solve multiple optimization problems (which must have same number of dimensions) without object reallocation penalty. INPUT PARAMETERS: State - structure used to store algorithm state X - new starting point. -- ALGLIB -- Copyright 30.07.2010 by Bochkanov Sergey *************************************************************************/void minlbfgsrestartfrom(minlbfgsstate &state, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlbfgsresults function/************************************************************************* L-BFGS algorithm results INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: X - array[0..N-1], solution Rep - optimization report: * Rep.TerminationType completetion code: * -8 internal integrity control detected infinite or NAN values in function/gradient. Abnormal termination signalled. * -2 rounding errors prevent further improvement. X contains best point found. * -1 incorrect parameters were specified * 1 relative function improvement is no more than EpsF. * 2 relative step is no more than EpsX. * 4 gradient norm is no more than EpsG * 5 MaxIts steps was taken * 7 stopping conditions are too stringent, further improvement is impossible * 8 terminated by user who called minlbfgsrequesttermination(). X contains point which was "current accepted" when termination request was submitted. * Rep.IterationsCount contains iterations count * NFEV countains number of function calculations -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minlbfgsresults(const minlbfgsstate &state, real_1d_array &x, minlbfgsreport &rep, const xparams _xparams = alglib::xdefault);
minlbfgsresultsbuf function/************************************************************************* L-BFGS algorithm results Buffered implementation of MinLBFGSResults which uses pre-allocated buffer to store X[]. If buffer size is too small, it resizes buffer. It is intended to be used in the inner cycles of performance critical algorithms where array reallocation penalty is too large to be ignored. -- ALGLIB -- Copyright 20.08.2010 by Bochkanov Sergey *************************************************************************/void minlbfgsresultsbuf(const minlbfgsstate &state, real_1d_array &x, minlbfgsreport &rep, const xparams _xparams = alglib::xdefault);
minlbfgssetcond function/************************************************************************* This function sets stopping conditions for L-BFGS optimization algorithm. INPUT PARAMETERS: State - structure which stores algorithm state EpsG - >=0 The subroutine finishes its work if the condition |v|<EpsG is satisfied, where: * |.| means Euclidian norm * v - scaled gradient vector, v[i]=g[i]*s[i] * g - gradient * s - scaling coefficients set by MinLBFGSSetScale() EpsF - >=0 The subroutine finishes its work if on k+1-th iteration the condition |F(k+1)-F(k)|<=EpsF*max{|F(k)|,|F(k+1)|,1} is satisfied. EpsX - >=0 The subroutine finishes its work if on k+1-th iteration the condition |v|<=EpsX is fulfilled, where: * |.| means Euclidian norm * v - scaled step vector, v[i]=dx[i]/s[i] * dx - ste pvector, dx=X(k+1)-X(k) * s - scaling coefficients set by MinLBFGSSetScale() MaxIts - maximum number of iterations. If MaxIts=0, the number of iterations is unlimited. Passing EpsG=0, EpsF=0, EpsX=0 and MaxIts=0 (simultaneously) will lead to automatic stopping criterion selection (small EpsX). -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minlbfgssetcond(minlbfgsstate &state, const double epsg, const double epsf, const double epsx, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
minlbfgssetpreccholesky function/************************************************************************* Modification of the preconditioner: Cholesky factorization of approximate Hessian is used. INPUT PARAMETERS: State - structure which stores algorithm state P - triangular preconditioner, Cholesky factorization of the approximate Hessian. array[0..N-1,0..N-1], (if larger, only leading N elements are used). IsUpper - whether upper or lower triangle of P is given (other triangle is not referenced) After call to this function preconditioner is changed to P (P is copied into the internal buffer). NOTE: you can change preconditioner "on the fly", during algorithm iterations. NOTE 2: P should be nonsingular. Exception will be thrown otherwise. -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minlbfgssetpreccholesky(minlbfgsstate &state, const real_2d_array &p, const bool isupper, const xparams _xparams = alglib::xdefault);
minlbfgssetprecdefault function/************************************************************************* Modification of the preconditioner: default preconditioner (simple scaling, same for all elements of X) is used. INPUT PARAMETERS: State - structure which stores algorithm state NOTE: you can change preconditioner "on the fly", during algorithm iterations. -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minlbfgssetprecdefault(minlbfgsstate &state, const xparams _xparams = alglib::xdefault);
minlbfgssetprecdiag function/************************************************************************* Modification of the preconditioner: diagonal of approximate Hessian is used. INPUT PARAMETERS: State - structure which stores algorithm state D - diagonal of the approximate Hessian, array[0..N-1], (if larger, only leading N elements are used). NOTE: you can change preconditioner "on the fly", during algorithm iterations. NOTE 2: D[i] should be positive. Exception will be thrown otherwise. NOTE 3: you should pass diagonal of approximate Hessian - NOT ITS INVERSE. -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minlbfgssetprecdiag(minlbfgsstate &state, const real_1d_array &d, const xparams _xparams = alglib::xdefault);
minlbfgssetprecscale function/************************************************************************* Modification of the preconditioner: scale-based diagonal preconditioning. This preconditioning mode can be useful when you don't have approximate diagonal of Hessian, but you know that your variables are badly scaled (for example, one variable is in [1,10], and another in [1000,100000]), and most part of the ill-conditioning comes from different scales of vars. In this case simple scale-based preconditioner, with H[i] = 1/(s[i]^2), can greatly improve convergence. IMPRTANT: you should set scale of your variables with MinLBFGSSetScale() call (before or after MinLBFGSSetPrecScale() call). Without knowledge of the scale of your variables scale-based preconditioner will be just unit matrix. INPUT PARAMETERS: State - structure which stores algorithm state -- ALGLIB -- Copyright 13.10.2010 by Bochkanov Sergey *************************************************************************/void minlbfgssetprecscale(minlbfgsstate &state, const xparams _xparams = alglib::xdefault);
minlbfgssetscale function/************************************************************************* This function sets scaling coefficients for LBFGS optimizer. ALGLIB optimizers use scaling matrices to test stopping conditions (step size and gradient are scaled before comparison with tolerances). Scale of the I-th variable is a translation invariant measure of: a) "how large" the variable is b) how large the step should be to make significant changes in the function Scaling is also used by finite difference variant of the optimizer - step along I-th axis is equal to DiffStep*S[I]. In most optimizers (and in the LBFGS too) scaling is NOT a form of preconditioning. It just affects stopping conditions. You should set preconditioner by separate call to one of the MinLBFGSSetPrec...() functions. There is special preconditioning mode, however, which uses scaling coefficients to form diagonal preconditioning matrix. You can turn this mode on, if you want. But you should understand that scaling is not the same thing as preconditioning - these are two different, although related forms of tuning solver. INPUT PARAMETERS: State - structure stores algorithm state S - array[N], non-zero scaling coefficients S[i] may be negative, sign doesn't matter. -- ALGLIB -- Copyright 14.01.2011 by Bochkanov Sergey *************************************************************************/void minlbfgssetscale(minlbfgsstate &state, const real_1d_array &s, const xparams _xparams = alglib::xdefault);
minlbfgssetstpmax function/************************************************************************* This function sets maximum step length INPUT PARAMETERS: State - structure which stores algorithm state StpMax - maximum step length, >=0. Set StpMax to 0.0 (default), if you don't want to limit step length. Use this subroutine when you optimize target function which contains exp() or other fast growing functions, and optimization algorithm makes too large steps which leads to overflow. This function allows us to reject steps that are too large (and therefore expose us to the possible overflow) without actually calculating function value at the x+stp*d. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minlbfgssetstpmax(minlbfgsstate &state, const double stpmax, const xparams _xparams = alglib::xdefault);
minlbfgssetxrep function/************************************************************************* This function turns on/off reporting. INPUT PARAMETERS: State - structure which stores algorithm state NeedXRep- whether iteration reports are needed or not If NeedXRep is True, algorithm will call rep() callback function if it is provided to MinLBFGSOptimize(). -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minlbfgssetxrep(minlbfgsstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_grad(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
// and its derivatives df/d0 and df/dx1
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
grad[0] = 400*pow(x[0]+3,3);
grad[1] = 4*pow(x[1]-3,3);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of
//
// f(x,y) = 100*(x+3)^4+(y-3)^4
//
// using LBFGS method, with:
// * initial point x=[0,0]
// * unit scale being set for all variables (see minlbfgssetscale for more info)
// * stopping criteria set to "terminate after short enough step"
//
// First, we create optimizer object and tune its properties.
//
// IMPORTANT: the LBFGS optimizer supports parallel parallel numerical
// differentiation ('callback parallelism'). This feature,
// which is present in commercial ALGLIB editions greatly
// accelerates optimization with numerical differentiation of
// an expensive target functions.
//
// Callback parallelism is usually beneficial when computing a
// numerical gradient requires more than several milliseconds.
// This particular example, of course, is not suited for
// callback parallelism.
//
// See ALGLIB Reference Manual, 'Working with commercial version'
// section, and comments on minlbfgsoptimize() function for
// more information.
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
double epsg = 0;
double epsf = 0;
double epsx = 0.0000000001;
ae_int_t maxits = 0;
minlbfgsstate state;
minlbfgscreate(1, x, state);
minlbfgssetcond(state, epsg, epsf, epsx, maxits);
minlbfgssetscale(state, s);
//
// Optimize and examine results.
//
minlbfgsreport rep;
alglib::minlbfgsoptimize(state, function1_grad);
minlbfgsresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,3]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_grad(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
// and its derivatives df/d0 and df/dx1
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
grad[0] = 400*pow(x[0]+3,3);
grad[1] = 4*pow(x[1]-3,3);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of f(x,y) = 100*(x+3)^4+(y-3)^4
// using LBFGS method.
//
// Several advanced techniques are demonstrated:
// * upper limit on step size
// * restart from new point
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
double epsg = 0;
double epsf = 0;
double epsx = 0.0000000001;
double stpmax = 0.1;
ae_int_t maxits = 0;
minlbfgsstate state;
minlbfgsreport rep;
// create and tune optimizer
minlbfgscreate(1, x, state);
minlbfgssetcond(state, epsg, epsf, epsx, maxits);
minlbfgssetstpmax(state, stpmax);
minlbfgssetscale(state, s);
// Set up OptGuard integrity checker which catches errors
// like nonsmooth targets or errors in the analytic gradient.
//
// OptGuard is essential at the early prototyping stages.
//
// NOTE: gradient verification needs 3*N additional function
// evaluations; DO NOT USE IT IN THE PRODUCTION CODE
// because it leads to unnecessary slowdown of your app.
minlbfgsoptguardsmoothness(state);
minlbfgsoptguardgradient(state, 0.001);
// first run
alglib::minlbfgsoptimize(state, function1_grad);
minlbfgsresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,3]
// second run - algorithm is restarted
x = "[10,10]";
minlbfgsrestartfrom(state, x);
alglib::minlbfgsoptimize(state, function1_grad);
minlbfgsresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,3]
// check OptGuard integrity report. Why do we need it at all?
// Well, try breaking the gradient by adding 1.0 to some
// of its components - OptGuard should report it as error.
// And it may also catch unintended errors too :)
optguardreport ogrep;
minlbfgsoptguardresults(state, ogrep);
printf("%s\n", ogrep.badgradsuspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc0suspected ? "true" : "false"); // EXPECTED: false
printf("%s\n", ogrep.nonc1suspected ? "true" : "false"); // EXPECTED: false
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_func(const real_1d_array &x, double &func, void *ptr)
{
//
// this callback calculates f(x0,x1) = 100*(x0+3)^4 + (x1-3)^4
//
func = 100*pow(x[0]+3,4) + pow(x[1]-3,4);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of
//
// f(x,y) = 100*(x+3)^4+(y-3)^4
//
// using numerical differentiation to calculate gradient.
//
// IMPORTANT: the LBFGS optimizer supports parallel parallel numerical
// differentiation ('callback parallelism'). This feature,
// which is present in commercial ALGLIB editions greatly
// accelerates optimization with numerical differentiation of
// an expensive target functions.
//
// Callback parallelism is usually beneficial when computing a
// numerical gradient requires more than several milliseconds.
// This particular example, of course, is not suited for
// callback parallelism.
//
// See ALGLIB Reference Manual, 'Working with commercial version'
// section, and comments on minlbfgsoptimize() function for
// more information.
//
real_1d_array x = "[0,0]";
double epsg = 0.0000000001;
double epsf = 0;
double epsx = 0;
double diffstep = 1.0e-6;
ae_int_t maxits = 0;
minlbfgsstate state;
minlbfgsreport rep;
minlbfgscreatef(1, x, diffstep, state);
minlbfgssetcond(state, epsg, epsf, epsx, maxits);
alglib::minlbfgsoptimize(state, function1_func);
minlbfgsresults(state, x, rep);
printf("%d\n", int(rep.terminationtype)); // EXPECTED: 4
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,3]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
minlm subpackage| minlm_d_restarts | Efficient restarts of LM optimizer | |
| minlm_d_v | Nonlinear least squares optimization using function vector only | |
| minlm_d_vb | Bound constrained nonlinear least squares optimization | |
| minlm_d_vj | Nonlinear least squares optimization using function vector and Jacobian |
minlmreport class/************************************************************************* Optimization report, filled by MinLMResults() function FIELDS: * TerminationType, completetion code: * -8 optimizer detected NAN/INF values either in the function itself, or in its Jacobian * -5 inappropriate solver was used: * solver created with minlmcreatefgh() used on problem with general linear constraints (set with minlmsetlc() call). * -3 constraints are inconsistent * 2 relative step is no more than EpsX. * 5 MaxIts steps was taken * 7 stopping conditions are too stringent, further improvement is impossible * 8 terminated by user who called MinLMRequestTermination(). X contains point which was "current accepted" when termination request was submitted. * F, objective value, SUM(f[i]^2) * IterationsCount, contains iterations count * NFunc, number of function calculations * NJac, number of Jacobi matrix calculations * NGrad, number of gradient calculations * NHess, number of Hessian calculations * NCholesky, number of Cholesky decomposition calculations *************************************************************************/class minlmreport { public: minlmreport(); minlmreport(const minlmreport &rhs); minlmreport& operator=(const minlmreport &rhs); virtual ~minlmreport(); ae_int_t iterationscount; ae_int_t terminationtype; double f; ae_int_t nfunc; ae_int_t njac; ae_int_t ngrad; ae_int_t nhess; ae_int_t ncholesky; };
minlmstate class/************************************************************************* Levenberg-Marquardt optimizer. This structure should be created using one of the MinLMCreate???() functions. You should not access its fields directly; use ALGLIB functions to work with it. *************************************************************************/class minlmstate { public: minlmstate(); minlmstate(const minlmstate &rhs); minlmstate& operator=(const minlmstate &rhs); virtual ~minlmstate(); };
minlmcreatev function/************************************************************************* IMPROVED LEVENBERG-MARQUARDT METHOD FOR NON-LINEAR LEAST SQUARES OPTIMIZATION DESCRIPTION: This function is used to find minimum of function which is represented as sum of squares: F(x) = f[0]^2(x[0],...,x[n-1]) + ... + f[m-1]^2(x[0],...,x[n-1]) using value of function vector f[] only. Finite differences are used to calculate Jacobian. REQUIREMENTS: This algorithm will request following information during its operation: * function vector f[] at given point X There are several overloaded versions of MinLMOptimize() function which correspond to different LM-like optimization algorithms provided by this unit. You should choose version which accepts fvec() callback. You can try to initialize MinLMState structure with VJ function and then use incorrect version of MinLMOptimize() (for example, version which works with general form function and does not accept function vector), but it will lead to exception being thrown after first attempt to calculate Jacobian. USAGE: 1. User initializes algorithm state with MinLMCreateV() call 2. User tunes solver parameters with MinLMSetCond(), MinLMSetStpMax() and other functions 3. User calls MinLMOptimize() function which takes algorithm state and callback functions. 4. User calls MinLMResults() to get solution 5. Optionally, user may call MinLMRestartFrom() to solve another problem with same N/M but another starting point and/or another function. MinLMRestartFrom() allows to reuse already initialized structure. INPUT PARAMETERS: N - dimension, N>1 * if given, only leading N elements of X are used * if not given, automatically determined from size of X M - number of functions f[i] X - initial solution, array[0..N-1] DiffStep- differentiation step, >0. By default, symmetric 3-point formula which provides good accuracy is used. It can be changed to a faster but less precise 2-point one with minlmsetnumdiff() function. OUTPUT PARAMETERS: State - structure which stores algorithm state See also MinLMIteration, MinLMResults. NOTES: 1. you may tune stopping conditions with MinLMSetCond() function 2. if target function contains exp() or other fast growing functions, and optimization algorithm makes too large steps which leads to overflow, use MinLMSetStpMax() function to bound algorithm's steps. -- ALGLIB -- Copyright 30.03.2009 by Bochkanov Sergey *************************************************************************/void minlmcreatev(const ae_int_t n, const ae_int_t m, const real_1d_array &x, const double diffstep, minlmstate &state, const xparams _xparams = alglib::xdefault); void minlmcreatev(const ae_int_t m, const real_1d_array &x, const double diffstep, minlmstate &state, const xparams _xparams = alglib::xdefault);
minlmcreatevj function/************************************************************************* IMPROVED LEVENBERG-MARQUARDT METHOD FOR NON-LINEAR LEAST SQUARES OPTIMIZATION DESCRIPTION: This function is used to find minimum of function which is represented as sum of squares: F(x) = f[0]^2(x[0],...,x[n-1]) + ... + f[m-1]^2(x[0],...,x[n-1]) using value of function vector f[] and Jacobian of f[]. REQUIREMENTS: This algorithm will request following information during its operation: * function vector f[] at given point X * function vector f[] and Jacobian of f[] (simultaneously) at given point There are several overloaded versions of MinLMOptimize() function which correspond to different LM-like optimization algorithms provided by this unit. You should choose version which accepts fvec() and jac() callbacks. First one is used to calculate f[] at given point, second one calculates f[] and Jacobian df[i]/dx[j]. You can try to initialize MinLMState structure with VJ function and then use incorrect version of MinLMOptimize() (for example, version which works with general form function and does not provide Jacobian), but it will lead to exception being thrown after first attempt to calculate Jacobian. USAGE: 1. User initializes algorithm state with MinLMCreateVJ() call 2. User tunes solver parameters with MinLMSetCond(), MinLMSetStpMax() and other functions 3. User calls MinLMOptimize() function which takes algorithm state and callback functions. 4. User calls MinLMResults() to get solution 5. Optionally, user may call MinLMRestartFrom() to solve another problem with same N/M but another starting point and/or another function. MinLMRestartFrom() allows to reuse already initialized structure. INPUT PARAMETERS: N - dimension, N>1 * if given, only leading N elements of X are used * if not given, automatically determined from size of X M - number of functions f[i] X - initial solution, array[0..N-1] OUTPUT PARAMETERS: State - structure which stores algorithm state NOTES: 1. you may tune stopping conditions with MinLMSetCond() function 2. if target function contains exp() or other fast growing functions, and optimization algorithm makes too large steps which leads to overflow, use MinLMSetStpMax() function to bound algorithm's steps. -- ALGLIB -- Copyright 30.03.2009 by Bochkanov Sergey *************************************************************************/void minlmcreatevj(const ae_int_t n, const ae_int_t m, const real_1d_array &x, minlmstate &state, const xparams _xparams = alglib::xdefault); void minlmcreatevj(const ae_int_t m, const real_1d_array &x, minlmstate &state, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlmiteration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool minlmiteration(minlmstate &state, const xparams _xparams = alglib::xdefault);
minlmoptguardgradient function/************************************************************************* This function activates/deactivates verification of the user-supplied analytic Jacobian. Upon activation of this option OptGuard integrity checker performs numerical differentiation of your target function vector at the initial point (note: future versions may also perform check at the final point) and compares numerical Jacobian with analytic one provided by you. If difference is too large, an error flag is set and optimization session continues. After optimization session is over, you can retrieve the report which stores both Jacobians, and specific components highlighted as suspicious by the OptGuard. The OptGuard report can be retrieved with minlmoptguardresults(). IMPORTANT: gradient check is a high-overhead option which will cost you about 3*N additional function evaluations. In many cases it may cost as much as the rest of the optimization session. YOU SHOULD NOT USE IT IN THE PRODUCTION CODE UNLESS YOU WANT TO CHECK DERIVATIVES PROVIDED BY SOME THIRD PARTY. NOTE: unlike previous incarnation of the gradient checking code, OptGuard does NOT interrupt optimization even if it discovers bad gradient. INPUT PARAMETERS: State - structure used to store algorithm state TestStep - verification step used for numerical differentiation: * TestStep=0 turns verification off * TestStep>0 activates verification You should carefully choose TestStep. Value which is too large (so large that function behavior is non- cubic at this scale) will lead to false alarms. Too short step will result in rounding errors dominating numerical derivative. You may use different step for different parameters by means of setting scale with minlmsetscale(). === EXPLANATION ========================================================== In order to verify gradient algorithm performs following steps: * two trial steps are made to X[i]-TestStep*S[i] and X[i]+TestStep*S[i], where X[i] is i-th component of the initial point and S[i] is a scale of i-th parameter * F(X) is evaluated at these trial points * we perform one more evaluation in the middle point of the interval * we build cubic model using function values and derivatives at trial points and we compare its prediction with actual value in the middle point -- ALGLIB -- Copyright 15.06.2014 by Bochkanov Sergey *************************************************************************/void minlmoptguardgradient(minlmstate &state, const double teststep, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlmoptguardresults function/************************************************************************* Results of OptGuard integrity check, should be called after optimization session is over. OptGuard checks analytic Jacobian against reference value obtained by numerical differentiation with user-specified step. NOTE: other optimizers perform additional OptGuard checks for things like C0/C1-continuity violations. However, LM optimizer can check only for incorrect Jacobian. The reason is that unlike line search methods LM optimizer does not perform extensive evaluations along the line. Thus, we simply do not have enough data to catch C0/C1-violations. This check is activated with minlmoptguardgradient() function. Following flags are set when these errors are suspected: * rep.badgradsuspected, and additionally: * rep.badgradfidx for specific function (Jacobian row) suspected * rep.badgradvidx for specific variable (Jacobian column) suspected * rep.badgradxbase, a point where gradient/Jacobian is tested * rep.badgraduser, user-provided gradient/Jacobian * rep.badgradnum, reference gradient/Jacobian obtained via numerical differentiation INPUT PARAMETERS: state - algorithm state OUTPUT PARAMETERS: rep - OptGuard report -- ALGLIB -- Copyright 21.11.2018 by Bochkanov Sergey *************************************************************************/void minlmoptguardresults(minlmstate &state, optguardreport &rep, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlmoptimize function/************************************************************************* This family of functions is used to start iterations of nonlinear optimizer These functions accept following parameters: state - algorithm state fvec - callback which calculates function vector fi[] at given point x jac - callback which calculates function vector fi[] and Jacobian jac at given point x rep - optional callback which is called after each iteration can be NULL ptr - optional pointer which is passed to func/grad/hess/jac/rep can be NULL CALLBACK PARALLELISM The MINLM optimizer supports parallel parallel numerical differentiation ('callback parallelism'). This feature, which is present in commercial ALGLIB editions, greatly accelerates optimization with numerical differentiation of an expensive target functions. Callback parallelism is usually beneficial when computing a numerical gradient requires more than several milliseconds. In this case the job of computing individual gradient components can be split between multiple threads. Even inexpensive targets can benefit from parallelism, if you have many variables. If you solve a curve fitting problem, i.e. the function vector is actually the same function computed at different points of a data points space, it may be better to use an LSFIT curve fitting solver, which offers more fine-grained parallelism due to knowledge of the problem structure. In particular, it can accelerate both numerical differentiation and problems with user-supplied gradients. ALGLIB Reference Manual, 'Working with commercial version' section, tells how to activate callback parallelism for your programming language. -- ALGLIB -- Copyright 03.12.2023 by Bochkanov Sergey *************************************************************************/void minlmoptimize(minlmstate &state, void (*fvec)(const real_1d_array &x, real_1d_array &fi, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault); void minlmoptimize(minlmstate &state, void (*fvec)(const real_1d_array &x, real_1d_array &fi, void *ptr), void (*jac)(const real_1d_array &x, real_1d_array &fi, real_2d_array &jac, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault);
minlmrequesttermination function/************************************************************************* This subroutine submits request for termination of running optimizer. It should be called from user-supplied callback when user decides that it is time to "smoothly" terminate optimization process. As result, optimizer stops at point which was "current accepted" when termination request was submitted and returns error code 8 (successful termination). INPUT PARAMETERS: State - optimizer structure NOTE: after request for termination optimizer may perform several additional calls to user-supplied callbacks. It does NOT guarantee to stop immediately - it just guarantees that these additional calls will be discarded later. NOTE: calling this function on optimizer which is NOT running will have no effect. NOTE: multiple calls to this function are possible. First call is counted, subsequent calls are silently ignored. -- ALGLIB -- Copyright 08.10.2014 by Bochkanov Sergey *************************************************************************/void minlmrequesttermination(minlmstate &state, const xparams _xparams = alglib::xdefault);
minlmrestartfrom function/************************************************************************* This subroutine restarts LM algorithm from new point. All optimization parameters are left unchanged. This function allows to solve multiple optimization problems (which must have same number of dimensions) without object reallocation penalty. INPUT PARAMETERS: State - structure used for reverse communication previously allocated with MinLMCreateXXX call. X - new starting point. -- ALGLIB -- Copyright 30.07.2010 by Bochkanov Sergey *************************************************************************/void minlmrestartfrom(minlmstate &state, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlmresults function/************************************************************************* Levenberg-Marquardt algorithm results NOTE: if you activated OptGuard integrity checking functionality and want to get OptGuard report, it can be retrieved with the help of minlmoptguardresults() function. INPUT PARAMETERS: State - algorithm state OUTPUT PARAMETERS: X - array[0..N-1], solution Rep - optimization report; includes termination codes and additional information. Termination codes are listed below, see comments for this structure for more info. Termination code is stored in rep.terminationtype field: * -8 optimizer detected NAN/INF values either in the function itself, or in its Jacobian * -3 constraints are inconsistent * 2 relative step is no more than EpsX. * 5 MaxIts steps was taken * 7 stopping conditions are too stringent, further improvement is impossible * 8 terminated by user who called minlmrequesttermination(). X contains point which was "current accepted" when termination request was submitted. rep.f contains SUM(f[i]^2) at X -- ALGLIB -- Copyright 10.03.2009 by Bochkanov Sergey *************************************************************************/void minlmresults(const minlmstate &state, real_1d_array &x, minlmreport &rep, const xparams _xparams = alglib::xdefault);
minlmresultsbuf function/************************************************************************* Levenberg-Marquardt algorithm results Buffered implementation of MinLMResults(), which uses pre-allocated buffer to store X[]. If buffer size is too small, it resizes buffer. It is intended to be used in the inner cycles of performance critical algorithms where array reallocation penalty is too large to be ignored. -- ALGLIB -- Copyright 10.03.2009 by Bochkanov Sergey *************************************************************************/void minlmresultsbuf(const minlmstate &state, real_1d_array &x, minlmreport &rep, const xparams _xparams = alglib::xdefault);
minlmsetacctype function/************************************************************************* This function is used to change acceleration settings You can choose between three acceleration strategies: * AccType=0, no acceleration. * AccType=1, secant updates are used to update quadratic model after each iteration. After fixed number of iterations (or after model breakdown) we recalculate quadratic model using analytic Jacobian or finite differences. Number of secant-based iterations depends on optimization settings: about 3 iterations - when we have analytic Jacobian, up to 2*N iterations - when we use finite differences to calculate Jacobian. AccType=1 is recommended when Jacobian calculation cost is prohibitively high (several Mx1 function vector calculations followed by several NxN Cholesky factorizations are faster than calculation of one M*N Jacobian). It should also be used when we have no Jacobian, because finite difference approximation takes too much time to compute. Table below list optimization protocols (XYZ protocol corresponds to MinLMCreateXYZ) and acceleration types they support (and use by default). ACCELERATION TYPES SUPPORTED BY OPTIMIZATION PROTOCOLS: protocol 0 1 comment V + + VJ + + FGH + DEFAULT VALUES: protocol 0 1 comment V x without acceleration it is so slooooooooow VJ x FGH x NOTE: this function should be called before optimization. Attempt to call it during algorithm iterations may result in unexpected behavior. NOTE: attempt to call this function with unsupported protocol/acceleration combination will result in exception being thrown. -- ALGLIB -- Copyright 14.10.2010 by Bochkanov Sergey *************************************************************************/void minlmsetacctype(minlmstate &state, const ae_int_t acctype, const xparams _xparams = alglib::xdefault);
minlmsetbc function/************************************************************************* This function sets boundary constraints for LM optimizer Boundary constraints are inactive by default (after initial creation). They are preserved until explicitly turned off with another SetBC() call. INPUT PARAMETERS: State - structure stores algorithm state BndL - lower bounds, array[N]. If some (all) variables are unbounded, you may specify very small number or -INF (latter is recommended because it will allow solver to use better algorithm). BndU - upper bounds, array[N]. If some (all) variables are unbounded, you may specify very large number or +INF (latter is recommended because it will allow solver to use better algorithm). NOTE 1: it is possible to specify BndL[i]=BndU[i]. In this case I-th variable will be "frozen" at X[i]=BndL[i]=BndU[i]. NOTE 2: this solver has following useful properties: * bound constraints are always satisfied exactly * function is evaluated only INSIDE area specified by bound constraints or at its boundary -- ALGLIB -- Copyright 14.01.2011 by Bochkanov Sergey *************************************************************************/void minlmsetbc(minlmstate &state, const real_1d_array &bndl, const real_1d_array &bndu, const xparams _xparams = alglib::xdefault);
minlmsetcond function/************************************************************************* This function sets stopping conditions for Levenberg-Marquardt optimization algorithm. INPUT PARAMETERS: State - structure which stores algorithm state EpsX - >=0 The subroutine finishes its work if on k+1-th iteration the condition |v|<=EpsX is fulfilled, where: * |.| means Euclidian norm * v - scaled step vector, v[i]=dx[i]/s[i] * dx - ste pvector, dx=X(k+1)-X(k) * s - scaling coefficients set by MinLMSetScale() Recommended values: 1E-9 ... 1E-12. MaxIts - maximum number of iterations. If MaxIts=0, the number of iterations is unlimited. Only Levenberg-Marquardt iterations are counted (L-BFGS/CG iterations are NOT counted because their cost is very low compared to that of LM). Passing EpsX=0 and MaxIts=0 (simultaneously) will lead to automatic stopping criterion selection (small EpsX). NOTE: it is not recommended to set large EpsX (say, 0.001). Because LM is a second-order method, it performs very precise steps anyway. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minlmsetcond(minlmstate &state, const double epsx, const ae_int_t maxits, const xparams _xparams = alglib::xdefault);
minlmsetlc function/************************************************************************* This function sets general linear constraints for LM optimizer Linear constraints are inactive by default (after initial creation). They are preserved until explicitly turned off with another minlmsetlc() call. INPUT PARAMETERS: State - structure stores algorithm state C - linear constraints, array[K,N+1]. Each row of C represents one constraint, either equality or inequality (see below): * first N elements correspond to coefficients, * last element corresponds to the right part. All elements of C (including right part) must be finite. CT - type of constraints, array[K]: * if CT[i]>0, then I-th constraint is C[i,*]*x >= C[i,n+1] * if CT[i]=0, then I-th constraint is C[i,*]*x = C[i,n+1] * if CT[i]<0, then I-th constraint is C[i,*]*x <= C[i,n+1] K - number of equality/inequality constraints, K>=0: * if given, only leading K elements of C/CT are used * if not given, automatically determined from sizes of C/CT IMPORTANT: if you have linear constraints, it is strongly recommended to set scale of variables with minlmsetscale(). QP solver which is used to calculate linearly constrained steps heavily relies on good scaling of input problems. IMPORTANT: solvers created with minlmcreatefgh() do not support linear constraints. NOTE: linear (non-bound) constraints are satisfied only approximately - there always exists some violation due to numerical errors and algorithmic limitations. NOTE: general linear constraints add significant overhead to solution process. Although solver performs roughly same amount of iterations (when compared with similar box-only constrained problem), each iteration now involves solution of linearly constrained QP subproblem, which requires ~3-5 times more Cholesky decompositions. Thus, if you can reformulate your problem in such way this it has only box constraints, it may be beneficial to do so. -- ALGLIB -- Copyright 14.01.2011 by Bochkanov Sergey *************************************************************************/void minlmsetlc(minlmstate &state, const real_2d_array &c, const integer_1d_array &ct, const ae_int_t k, const xparams _xparams = alglib::xdefault); void minlmsetlc(minlmstate &state, const real_2d_array &c, const integer_1d_array &ct, const xparams _xparams = alglib::xdefault);
minlmsetnonmonotonicsteps function/************************************************************************* This function is used to activate/deactivate nonmonotonic steps. Such steps may improve convergence on noisy problems or ones with minor smoothness defects. In its standard mode, LM solver compares value at the trial point f[1] with the value at the current point f[0]. Only steps that decrease f() are accepted. When the nonmonotonic mode is activated, f[1] is compared with maximum over several previous locations: max(f[0],f[-1],...,f[-CNT]). We still accept only steps that decrease f(), however our reference value has changed. The net results is that f[1]>f[0] are now allowed. Nonmonotonic steps can help to handle minor defects in the objective (e.g. small noise, discontinuous jumps or nonsmoothness). However, it is important that the overall shape of the problem is still smooth. It may also help to minimize perfectly smooth targets with complex geometries by allowing to jump through curved valleys. However, sometimes nonmonotonic steps degrade convergence by allowing an optimizer to wander too far away from the solution, so this feature should be used only after careful testing. INPUT PARAMETERS: State - structure stores algorithm state Cnt - nonmonotonic memory length, Cnt>=0: * 0 for traditional monotonic steps * 2..3 is recommended for the nonmonotonic optimization -- ALGLIB -- Copyright 07.04.2024 by Bochkanov Sergey *************************************************************************/void minlmsetnonmonotonicsteps(minlmstate &state, const ae_int_t cnt, const xparams _xparams = alglib::xdefault);
minlmsetnumdiff function/************************************************************************* This function sets specific finite difference formula to be used for numerical differentiation. It works only for optimizers created with minlmcreatev() function; in other cases it has no effect. INPUT PARAMETERS: State - structure previously allocated with MinLMCreateV() call. FormulaType - formula type: * 3 for a 3-point formula, which is also known as a symmetric difference quotient (the formula actually uses only two function values per variable: at x+h and x-h). A good choice for medium-accuracy setups, a default option. * 2 for a forward (or backward, depending on variable bounds) finite difference (f(x+h)-f(x))/h. This formula has the lowest accuracy. However, it is 4x faster than the 5-point formula and 2x faster than the 3-point one because, in addition to the central value f(x), it needs only one additional function evaluation per variable. -- ALGLIB -- Copyright 03.12.2024 by Bochkanov Sergey *************************************************************************/void minlmsetnumdiff(minlmstate &state, const ae_int_t formulatype, const xparams _xparams = alglib::xdefault);
minlmsetscale function/************************************************************************* This function sets scaling coefficients for LM optimizer. ALGLIB optimizers use scaling matrices to test stopping conditions (step size and gradient are scaled before comparison with tolerances). Scale of the I-th variable is a translation invariant measure of: a) "how large" the variable is b) how large the step should be to make significant changes in the function Generally, scale is NOT considered to be a form of preconditioner. But LM optimizer is unique in that it uses scaling matrix both in the stopping condition tests and as Marquardt damping factor. Proper scaling is very important for the algorithm performance. It is less important for the quality of results, but still has some influence (it is easier to converge when variables are properly scaled, so premature stopping is possible when very badly scalled variables are combined with relaxed stopping conditions). INPUT PARAMETERS: State - structure stores algorithm state S - array[N], non-zero scaling coefficients S[i] may be negative, sign doesn't matter. -- ALGLIB -- Copyright 14.01.2011 by Bochkanov Sergey *************************************************************************/void minlmsetscale(minlmstate &state, const real_1d_array &s, const xparams _xparams = alglib::xdefault);
minlmsetstpmax function/************************************************************************* This function sets maximum step length INPUT PARAMETERS: State - structure which stores algorithm state StpMax - maximum step length, >=0. Set StpMax to 0.0, if you don't want to limit step length. Use this subroutine when you optimize target function which contains exp() or other fast growing functions, and optimization algorithm makes too large steps which leads to overflow. This function allows us to reject steps that are too large (and therefore expose us to the possible overflow) without actually calculating function value at the x+stp*d. NOTE: non-zero StpMax leads to moderate performance degradation because intermediate step of preconditioned L-BFGS optimization is incompatible with limits on step size. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minlmsetstpmax(minlmstate &state, const double stpmax, const xparams _xparams = alglib::xdefault);
minlmsetxrep function/************************************************************************* This function turns on/off reporting. INPUT PARAMETERS: State - structure which stores algorithm state NeedXRep- whether iteration reports are needed or not If NeedXRep is True, algorithm will call rep() callback function if it is provided to MinLMOptimize(). Both Levenberg-Marquardt and internal L-BFGS iterations are reported. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/void minlmsetxrep(minlmstate &state, const bool needxrep, const xparams _xparams = alglib::xdefault);
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_fvec(const real_1d_array &x, real_1d_array &fi, void *ptr)
{
//
// this callback calculates
// f0(x0,x1) = 100*(x0+3)^4,
// f1(x0,x1) = (x1-3)^4
//
fi[0] = 10*pow(x[0]+3,2);
fi[1] = pow(x[1]-3,2);
}
void function2_fvec(const real_1d_array &x, real_1d_array &fi, void *ptr)
{
//
// this callback calculates
// f0(x0,x1) = x0^2+1
// f1(x0,x1) = x1-1
//
fi[0] = x[0]*x[0]+1;
fi[1] = x[1]-1;
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of F(x0,x1) = f0^2+f1^2, where
//
// f0(x0,x1) = 10*(x0+3)^2
// f1(x0,x1) = (x1-3)^2
//
// using several starting points and efficient restarts.
//
real_1d_array x;
double epsx = 0.0000000001;
ae_int_t maxits = 0;
minlmstate state;
minlmreport rep;
//
// create optimizer using minlmcreatev()
//
x = "[10,10]";
minlmcreatev(2, x, 0.0001, state);
minlmsetcond(state, epsx, maxits);
alglib::minlmoptimize(state, function1_fvec);
minlmresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,+3]
//
// restart optimizer using minlmrestartfrom()
//
// we can use different starting point, different function,
// different stopping conditions, but the problem size
// must remain unchanged.
//
x = "[4,4]";
minlmrestartfrom(state, x);
alglib::minlmoptimize(state, function2_fvec);
minlmresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [0,1]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_fvec(const real_1d_array &x, real_1d_array &fi, void *ptr)
{
//
// this callback calculates
// f0(x0,x1) = 100*(x0+3)^4,
// f1(x0,x1) = (x1-3)^4
//
fi[0] = 10*pow(x[0]+3,2);
fi[1] = pow(x[1]-3,2);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of F(x0,x1) = f0^2+f1^2, where
//
// f0(x0,x1) = 10*(x0+3)^2
// f1(x0,x1) = (x1-3)^2
//
// using "V" mode of the Levenberg-Marquardt optimizer (function values only,
// no Jacobian information). The optimization algorithm uses function vector
//
// f[] = {f1,f2}
//
// No other information (Jacobian, gradient, etc.) is needed.
//
// IMPORTANT: the MINLM optimizer supports parallel parallel numerical
// differentiation ('callback parallelism'). This feature,
// which is present in commercial ALGLIB editions, greatly
// accelerates optimization with numerical differentiation of
// an expensive target functions.
//
// Callback parallelism is usually beneficial when computing a
// numerical gradient requires more than several milliseconds.
// This particular example, of course, is not suited for
// callback parallelism.
//
// If you solve a curve fitting problem, i.e. the function
// vector is actually the same function computed at different
// points of a data points space, then it may be better to use
// an LSFIT curve fitting solver, which offers more fine-grained
// parallelism due to knowledge of the problem structure. In
// particular, it can accelerate both numerical differentiation
// and problems with user-supplied gradients.
//
// See ALGLIB Reference Manual, 'Working with commercial version'
// section, and comments on minlmoptimize() function for
// more information.
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
double epsx = 0.0000000001;
ae_int_t maxits = 0;
minlmstate state;
minlmreport rep;
//
// Create optimizer, tell it to:
// * use numerical differentiation with step equal to 0.0001
// * use unit scale for all variables (s is a unit vector)
// * stop after short enough step (less than epsx)
//
minlmcreatev(2, x, 0.0001, state);
minlmsetcond(state, epsx, maxits);
minlmsetscale(state, s);
//
// A new feature: nonmonotonic steps!
//
// In theory, LM solver should be used only for smooth and continuous objectives. In practice,
// real life objectives are often results of some long numerical simulation and have defects
// like small discontinuous jumps, small noise or minor nonsmoothness. Such defects often
// prevent optimization progress because an uphill step may be required to move past the
// defect.
//
// Nonmonotonic steps allow to tolerate a minor and temporary increase in the objective,
// allowing progress beyond an obstacle. This feature is also essential for ill-conditioned
// targets - it allows the solver to jump through a curved valley instead of navigating along
// its bottom.
//
// However, sometimes nonmonotonic steps degrade convergence by allowing an optimizer to
// wander too far away from the solution, so this feature should be used only after careful
// testing.
//
// The code below sets the nonmonotonic memory length to 0 (which means traditional monotonic
// optimization). If you want to try a nonmonotonic optimization, use 2 or 3 as a recommended
// memory length.
//
minlmsetnonmonotonicsteps(state, 0);
//
// Optimize
//
alglib::minlmoptimize(state, function1_fvec);
//
// Test optimization results
//
// NOTE: because we use numerical differentiation, we do not
// verify Jacobian correctness - it is always "correct".
// However, if you switch to analytic gradient, consider
// checking it with OptGuard (see other examples).
//
minlmresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,+3]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_fvec(const real_1d_array &x, real_1d_array &fi, void *ptr)
{
//
// this callback calculates
// f0(x0,x1) = 100*(x0+3)^4,
// f1(x0,x1) = (x1-3)^4
//
fi[0] = 10*pow(x[0]+3,2);
fi[1] = pow(x[1]-3,2);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of F(x0,x1) = f0^2+f1^2, where
//
// f0(x0,x1) = 10*(x0+3)^2
// f1(x0,x1) = (x1-3)^2
//
// with box constraints
//
// -1 <= x0 <= +1
// -1 <= x1 <= +1
//
// using "V" mode of the Levenberg-Marquardt optimizer. The optimization
// algorithm uses function vector f[] = {f1,f2}. No other information
// (Jacobian, gradient, etc.) is needed.
//
// IMPORTANT: the MINLM optimizer supports parallel parallel numerical
// differentiation ('callback parallelism'). This feature,
// which is present in commercial ALGLIB editions, greatly
// accelerates optimization with numerical differentiation of
// an expensive target functions.
//
// Callback parallelism is usually beneficial when computing a
// numerical gradient requires more than several milliseconds.
// This particular example, of course, is not suited for
// callback parallelism.
//
// If you solve a curve fitting problem, i.e. the function
// vector is actually the same function computed at different
// points of a data points space, then it may be better to use
// an LSFIT curve fitting solver, which offers more fine-grained
// parallelism due to knowledge of the problem structure. In
// particular, it can accelerate both numerical differentiation
// and problems with user-supplied gradients.
//
// See ALGLIB Reference Manual, 'Working with commercial version'
// section, and comments on minlmoptimize() function for
// more information.
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
real_1d_array bndl = "[-1,-1]";
real_1d_array bndu = "[+1,+1]";
double epsx = 0.0000000001;
ae_int_t maxits = 0;
minlmstate state;
//
// Create optimizer, tell it to:
// * use numerical differentiation with step equal to 1.0
// * use unit scale for all variables (s is a unit vector)
// * stop after short enough step (less than epsx)
// * set box constraints
//
minlmcreatev(2, x, 0.0001, state);
minlmsetbc(state, bndl, bndu);
minlmsetcond(state, epsx, maxits);
minlmsetscale(state, s);
//
// A new feature: nonmonotonic steps!
//
// In theory, LM solver should be used only for smooth and continuous objectives. In practice,
// real life objectives are often results of some long numerical simulation and have defects
// like small discontinuous jumps, small noise or minor nonsmoothness. Such defects often
// prevent optimization progress because an uphill step may be required to move past the
// defect.
//
// Nonmonotonic steps allow to tolerate a minor and temporary increase in the objective,
// allowing progress beyond an obstacle. This feature is also essential for ill-conditioned
// targets - it allows the solver to jump through a curved valley instead of navigating along
// its bottom.
//
// However, sometimes nonmonotonic steps degrade convergence by allowing an optimizer to
// wander too far away from the solution, so this feature should be used only after careful
// testing.
//
// The code below sets the nonmonotonic memory length to 0 (which means traditional monotonic
// optimization). If you want to try a nonmonotonic optimization, use 2 or 3 as a recommended
// memory length.
//
minlmsetnonmonotonicsteps(state, 0);
//
// Optimize
//
alglib::minlmoptimize(state, function1_fvec);
//
// Test optimization results
//
// NOTE: because we use numerical differentiation, we do not
// verify Jacobian correctness - it is always "correct".
// However, if you switch to analytic gradient, consider
// checking it with OptGuard (see other examples).
//
minlmreport rep;
minlmresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-1,+1]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "optimization.h"
using namespace alglib;
void function1_fvec(const real_1d_array &x, real_1d_array &fi, void *ptr)
{
//
// this callback calculates
// f0(x0,x1) = 100*(x0+3)^4,
// f1(x0,x1) = (x1-3)^4
//
fi[0] = 10*pow(x[0]+3,2);
fi[1] = pow(x[1]-3,2);
}
void function1_jac(const real_1d_array &x, real_1d_array &fi, real_2d_array &jac, void *ptr)
{
//
// this callback calculates
// f0(x0,x1) = 100*(x0+3)^4,
// f1(x0,x1) = (x1-3)^4
// and Jacobian matrix J = [dfi/dxj]
//
fi[0] = 10*pow(x[0]+3,2);
fi[1] = pow(x[1]-3,2);
jac[0][0] = 20*(x[0]+3);
jac[0][1] = 0;
jac[1][0] = 0;
jac[1][1] = 2*(x[1]-3);
}
int main(int argc, char **argv)
{
try
{
//
// This example demonstrates minimization of F(x0,x1) = f0^2+f1^2, where
//
// f0(x0,x1) = 10*(x0+3)^2
// f1(x0,x1) = (x1-3)^2
//
// using "VJ" mode of the Levenberg-Marquardt optimizer. The optimization
// algorithm uses the function vector f[] = {f1,f2} and the Jacobian
// matrix J = {dfi/dxj}, both of them provided by user.
//
// IMPORTANT: the MINLM optimizer supports parallel numerical
// differentiation ('callback parallelism'). This feature,
// which is present in commercial ALGLIB editions, greatly
// accelerates optimization with numerical differentiation of
// an expensive target functions.
//
// Callback parallelism is usually beneficial when computing a
// numerical gradient requires more than several milliseconds.
// This particular example, of course, is not suited for
// callback parallelism.
//
// If you solve a curve fitting problem, i.e. the function
// vector is actually the same function computed at different
// points of a data points space, then it may be better to use
// an LSFIT curve fitting solver, which offers more fine-grained
// parallelism due to knowledge of the problem structure. In
// particular, it can accelerate both numerical differentiation
// and problems with user-supplied gradients.
//
// See ALGLIB Reference Manual, 'Working with commercial version'
// section, and comments on minlmoptimize() function for
// more information.
//
real_1d_array x = "[0,0]";
real_1d_array s = "[1,1]";
double epsx = 0.0000000001;
ae_int_t maxits = 0;
minlmstate state;
//
// Create optimizer, tell it to:
// * use analytic gradient provided by user
// * use unit scale for all variables (s is a unit vector)
// * stop after short enough step (less than epsx)
//
minlmcreatevj(2, x, state);
minlmsetcond(state, epsx, maxits);
minlmsetscale(state, s);
//
// A new feature: nonmonotonic steps!
//
// In theory, LM solver should be used only for smooth and continuous objectives. In practice,
// real life objectives are often results of some long numerical simulation and have defects
// like small discontinuous jumps, small noise or minor nonsmoothness. Such defects often
// prevent optimization progress because an uphill step may be required to move past the
// defect.
//
// Nonmonotonic steps allow to tolerate a minor and temporary increase in the objective,
// allowing progress beyond an obstacle. This feature is also essential for ill-conditioned
// targets - it allows the solver to jump through a curved valley instead of navigating along
// its bottom.
//
// However, sometimes nonmonotonic steps degrade convergence by allowing an optimizer to
// wander too far away from the solution, so this feature should be used only after careful
// testing.
//
// The code below sets the nonmonotonic memory length to 0 (which means traditional monotonic
// optimization). If you want to try a nonmonotonic optimization, use 2 or 3 as a recommended
// memory length.
//
minlmsetnonmonotonicsteps(state, 0);
//
// Optimize
//
alglib::minlmoptimize(state, function1_fvec, function1_jac);
//
// Test optimization results
//
minlmreport rep;
minlmresults(state, x, rep);
printf("%s\n", x.tostring(2).c_str()); // EXPECTED: [-3,+3]
}
catch(alglib::ap_error alglib_exception)
{
printf("ALGLIB exception with message '%s'\n", alglib_exception.msg.c_str());
return 1;
}
return 0;
}
minlpsolvers subpackage| minlp_bnb_dfo | MINLP problem solved with branch-and-bound and MIVNS | |
| minlp_expensive_dfo | Derivative-free MINLP problem with expensive simulation-based objective/constraints |
minlpsolverreport class/************************************************************************* This structure stores the optimization report. The following fields are set by all MINLP solvers: * f objective value at the solution * nfev number of value/gradient evaluations * terminationtype termination type (see below) The BBGD solver additionally sets the following fields: * pdgap final primal-dual gap * ntreenodes number of B&B tree nodes traversed * nsubproblems total number of NLP relaxations solved; can be larger than ntreenodes because of restarts * nnodesbeforefeasibility number of nodes evaluated before finding first integer feasible solution TERMINATION CODES TerminationType field contains completion code, which can be either FAILURE code or SUCCESS code. === FAILURE CODE === -33 timed out, failed to find a feasible point within time limit or iteration budget -8 internal integrity control detected infinite or NAN values in function/gradient, recovery was impossible. Abnormal termination signaled. -3 integer infeasibility is signaled: * for convex problems: proved to be infeasible * for nonconvex problems: a primal feasible point is nonexistent or too difficult to find === SUCCESS CODE === 2 successful solution: * for BBGD - entire tree was scanned * for MIVNS - either entire integer grid was scanned, or the neighborhood size based condition was triggered (in future versions other criteria may be introduced) 5 a primal feasible point was found, but time or iteration limit was exhausted but we failed to find a better one or prove its optimality; the best point so far is returned. *************************************************************************/class minlpsolverreport { public: minlpsolverreport(); minlpsolverreport(const minlpsolverreport &rhs); minlpsolverreport& operator=(const minlpsolverreport &rhs); virtual ~minlpsolverreport(); double f; ae_int_t nfev; ae_int_t nsubproblems; ae_int_t ntreenodes; ae_int_t nnodesbeforefeasibility; ae_int_t terminationtype; double pdgap; };
minlpsolverstate class/************************************************************************* This object stores nonlinear optimizer state. You should use functions provided by MinNLC subpackage to work with this object *************************************************************************/class minlpsolverstate { public: minlpsolverstate(); minlpsolverstate(const minlpsolverstate &rhs); minlpsolverstate& operator=(const minlpsolverstate &rhs); virtual ~minlpsolverstate(); };
minlpsolveraddlc2 function/************************************************************************* This function appends two-sided linear constraint AL <= A*x <= AU to the list of currently present sparse constraints. Constraint is passed in compressed format: as list of non-zero entries of coefficient vector A. Such approach is more efficient than dense storage for highly sparse constraint vectors. INPUT PARAMETERS: State - structure previously allocated with minlpsolvercreate() call. IdxA - array[NNZ], indexes of non-zero elements of A: * can be unsorted * can include duplicate indexes (corresponding entries of ValA[] will be summed) ValA - array[NNZ], values of non-zero elements of A NNZ - number of non-zero coefficients in A AL, AU - lower and upper bounds; * AL=AU => equality constraint A*x * AL<AU => two-sided constraint AL<=A*x<=AU * AL=-INF => one-sided constraint A*x<=AU * AU=+INF => one-sided constraint AL<=A*x * AL=-INF, AU=+INF => constraint is ignored -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpsolveraddlc2(minlpsolverstate &state, const integer_1d_array &idxa, const real_1d_array &vala, const ae_int_t nnz, const double al, const double au, const xparams _xparams = alglib::xdefault);
minlpsolveraddlc2dense function/************************************************************************* This function appends a two-sided linear constraint AL <= A*x <= AU to the matrix of dense constraints. INPUT PARAMETERS: State - structure previously allocated with minlpsolvercreate() call. A - linear constraint coefficient, array[N], right side is NOT included. AL, AU - lower and upper bounds; * AL=AU => equality constraint Ai*x * AL<AU => two-sided constraint AL<=A*x<=AU * AL=-INF => one-sided constraint Ai*x<=AU * AU=+INF => one-sided constraint AL<=Ai*x * AL=-INF, AU=+INF => constraint is ignored -- ALGLIB -- Copyright 15.04.2024 by Bochkanov Sergey *************************************************************************/void minlpsolveraddlc2dense(minlpsolverstate &state, const real_1d_array &a, const double al, const double au, const xparams _xparams = alglib::xdefault);
minlpsolveraddlc2sparsefromdense function/************************************************************************* This function appends two-sided linear constraint AL <= A*x <= AU to the list of currently present sparse constraints. Constraint vector A is passed as a dense array which is internally sparsified by this function. INPUT PARAMETERS: State - structure previously allocated with minlpsolvercreate() call. DA - array[N], constraint vector AL, AU - lower and upper bounds; * AL=AU => equality constraint A*x * AL<AU => two-sided constraint AL<=A*x<=AU * AL=-INF => one-sided constraint A*x<=AU * AU=+INF => one-sided constraint AL<=A*x * AL=-INF, AU=+INF => constraint is ignored -- ALGLIB -- Copyright 19.07.2018 by Bochkanov Sergey *************************************************************************/void minlpsolveraddlc2sparsefromdense(minlpsolverstate &state, const real_1d_array &da, const double al, const double au, const xparams _xparams = alglib::xdefault);
minlpsolveraddnlc2 function/************************************************************************* This function APPENDS a two-sided nonlinear constraint to the list. In fact, this function adds constraint bounds. A constraints itself (a function) is passed to the MINLPSolverOptimize() method as a callback. See comments on MINLPSolverSetNLC2() for more information about callback structure. The function adds a two-sided nonlinear constraint NL<=C(x)<=NU, where * NL=NU => I-th row is an equality constraint Ci(x)=NL * NL<NU => I-th tow is a two-sided constraint NL<=Ci(x)<=NU * NL=-INF => I-th row is an one-sided constraint Ci(x)<=NU * NU=+INF => I-th row is an one-sided constraint NL<=Ci(x) * NL=-INF, NU=+INF => constraint is ignored NOTE: you may combine nonlinear constraints with linear/boundary ones. If your problem has mixed constraints, you may explicitly specify some of them as linear or box ones. It helps the optimizer to handle them more efficiently. INPUT PARAMETERS: State - structure previously allocated with MINLPSolverCreate call. NL - lower bound, can be -INF NU - upper bound, can be +INF NOTE 1: nonlinear constraints are satisfied only approximately! It is possible that the algorithm will evaluate the function outside of the feasible area! NOTE 2: algorithm scales variables according to the scale specified by MINLPSolverSetScale() function, so it can handle problems with badly scaled variables (as long as we KNOW their scales). However, there is no way to automatically scale nonlinear constraints. Inappropriate scaling of nonlinear constraints may ruin convergence. Solving problem with constraint "1000*G0(x)=0" is NOT the same as solving it with constraint "0.001*G0(x)=0". It means that YOU are the one who is responsible for the correct scaling of the nonlinear constraints Gi(x) and Hi(x). We recommend you to scale nonlinear constraints in such a way that the Jacobian rows have approximately unit magnitude (for problems with unit scale) or have magnitude approximately equal to 1/S[i] (where S is a scale set by MINLPSolverSetScale() function). NOTE 3: use addnlc2masked() in order to specify variable mask. Masks are essential for derivative-free optimization because they provide important information about relevant and irrelevant variables. -- ALGLIB -- Copyright 05.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolveraddnlc2(minlpsolverstate &state, const double nl, const double nu, const xparams _xparams = alglib::xdefault);
minlpsolveraddnlc2masked function/************************************************************************* This function APPENDS a two-sided nonlinear constraint to the list, with the variable mask being specified as a compressed index array. A variable mask is a set of variables actually appearing in the constraint. ----- ABOUT VARIABLE MASKS ----------------------------------------------- Variable masks provide crucial information for derivative-free solvers, greatly accelerating surrogate model construction. This applies to both continuous and integral variables, with results for binary variables being more pronounced. Up to 2x improvement in convergence speed has been observed for sufficiently sparse MINLP problems. NOTE: In order to unleash the full potential of variable masking, it is important to provide masks for objective as well as all nonlinear constraints. Even partial information matters, i.e. if you are 100% sure that your black-box function does not depend on some variables, but unsure about other ones, mark surely irrelevant variables, and tell the solver that other ones may be relevant. NOTE: the solver is may behave unpredictably if some relevant variable is not included into the mask. Most likely it will fail to converge, although it sometimes possible to converge to solution even with incorrectly specified mask. NOTE: minlpsolversetobjectivemask() can be used to set variable mask for the objective. NOTE: Masks are ignored by branch-and-bound-type solvers relying on analytic gradients. ----- ABOUT NONLINEAR CONSTRAINTS ---------------------------------------- In fact, this function adds constraint bounds. A constraint itself (a function) is passed to the MINLPSolverOptimize() method as a callback. See comments on MINLPSolverSetNLC2() for more information about callback structure. The function adds a two-sided nonlinear constraint NL<=C(x)<=NU, where * NL=NU => I-th row is an equality constraint Ci(x)=NL * NL<NU => I-th tow is a two-sided constraint NL<=Ci(x)<=NU * NL=-INF => I-th row is an one-sided constraint Ci(x)<=NU * NU=+INF => I-th row is an one-sided constraint NL<=Ci(x) * NL=-INF, NU=+INF => constraint is ignored NOTE: you may combine nonlinear constraints with linear/boundary ones. If your problem has mixed constraints, you may explicitly specify some of them as linear or box ones. It helps the optimizer to handle them more efficiently. INPUT PARAMETERS: State - structure previously allocated with MINLPSolverCreate call. NL - lower bound, can be -INF NU - upper bound, can be +INF VarIdx - array[NMSK], with potentially unsorted and non-distinct indexes (the function will sort and merge duplicates). If a variable index K appears in the list, it means that the constraint potentially depends on K-th variable. If a variable index K does NOT appear in the list, it means that the constraint does NOT depend on K-th variable. The array can have more than NMSK elements, in which case only leading NMSK will be used. NMSK - NMSK>=0, VarIdx[] size: * NMSK>0 means that the constraint depends on up to NMSK variables whose indexes are stored in VarIdx[] * NMSK=0 means that the constraint is a constant function; the solver may fail if it is not actually the case. NOTE 1: nonlinear constraints are satisfied only approximately! It is possible that the algorithm will evaluate the function outside of the feasible area! NOTE 2: algorithm scales variables according to the scale specified by MINLPSolverSetScale() function, so it can handle problems with badly scaled variables (as long as we KNOW their scales). However, there is no way to automatically scale nonlinear constraints. Inappropriate scaling of nonlinear constraints may ruin convergence. Solving problem with constraint "1000*G0(x)=0" is NOT the same as solving it with constraint "0.001*G0(x)=0". It means that YOU are the one who is responsible for the correct scaling of the nonlinear constraints Gi(x) and Hi(x). We recommend you to scale nonlinear constraints in such a way that the Jacobian rows have approximately unit magnitude (for problems with unit scale) or have magnitude approximately equal to 1/S[i] (where S is a scale set by MINLPSolverSetScale() function). -- ALGLIB -- Copyright 05.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolveraddnlc2masked(minlpsolverstate &state, const double nl, const double nu, const integer_1d_array &varidx, const ae_int_t nmsk, const xparams _xparams = alglib::xdefault);
minlpsolvercautiousinternalparallelism function/************************************************************************* This function controls adaptive internal parallelism, i.e. algorithm used by the solver to adaptively decide whether parallel acceleration of solver's internal calculations (B&B code, SQP, parallel linear algebra) should be actually used or not. This function tells the solver to do calculations in the single-threaded mode until statistics prove that iteration cost justified activating multithreading. This way solver does not suffer slow-down on problems with small iteration overhead (<1ms per iteration), at the cost of spending initial 10-20 ms in the single-threaded mode even on difficult problems that justify parallelism usage. Use MINLPSolver.FavorInternalParallelism() to use parallelism until it is proven to be useless. NOTE: the internal parallelism is distinct from the callback parallelism. The former is the ability to utilize parallelism to speed-up solvers own internal calculations, while the latter is the ability to perform several callback evaluations at once. Aside from performance considerations, the internal parallelism is entirely transparent to the user. The callback parallelism requries the user to write a thread-safe, reentrant callback. NOTE: in order to use internal parallelism, adaptive or not, the user must activate it by specifying alglib::parallel in flags or global threading settings. ALGLIB for C++ must be compiled in the OS-aware mode. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolvercautiousinternalparallelism(minlpsolverstate &state, const xparams _xparams = alglib::xdefault);
minlpsolvercreate function/************************************************************************* MIXED INTEGER NONLINEAR PROGRAMMING SOLVER DESCRIPTION: The subroutine minimizes a function F(x) of N arguments subject to any combination of: * box constraints * linear equality/inequality/range constraints CL<=Ax<=CU * nonlinear equality/inequality/range constraints HL<=Hi(x)<=HU * integrality constraints on some variables REQUIREMENTS: * F(), H() are continuously differentiable on the feasible set and its neighborhood * starting point X0, which can be infeasible INPUT PARAMETERS: N - problem dimension, N>0: * if given, only leading N elements of X are used * if not given, automatically determined from size ofX X - starting point, array[N]: * it is better to set X to a feasible point * but X can be infeasible, in which case algorithm will try to find feasible point first, using X as initial approximation. OUTPUT PARAMETERS: State - structure stores algorithm state -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolvercreate(const ae_int_t n, const real_1d_array &x, minlpsolverstate &state, const xparams _xparams = alglib::xdefault); void minlpsolvercreate(const real_1d_array &x, minlpsolverstate &state, const xparams _xparams = alglib::xdefault);
minlpsolverfavorinternalparallelism function/************************************************************************* This function controls adaptive internal parallelism, i.e. algorithm used by the solver to adaptively decide whether parallel acceleration of solver's internal calculations (B&B code, SQP, parallel linear algebra) should be actually used or not. This function tells the solver to favor parallelism, i.e. utilize multithreading (when allowed by the user) until statistics prove that overhead from starting/stopping worker threads is too large. This way solver gets the best performance on problems with significant amount of internal calculations (large QP/MIQP subproblems, lengthy surrogate model optimization sessions) from the very beginning. The price is that problems with small solver overhead that does not justify internal parallelism (<1ms per iteration) will suffer slowdown for several initial 10-20 milliseconds until the solver proves that parallelism makes no sense Use MINLPSolver.CautiousInternalParallelism() to avoid slowing down the solver on easy problems. NOTE: the internal parallelism is distinct from the callback parallelism. The former is the ability to utilize parallelism to speed-up solvers own internal calculations, while the latter is the ability to perform several callback evaluations at once. Aside from performance considerations, the internal parallelism is entirely transparent to the user. The callback parallelism requries the user to write a thread-safe, reentrant callback. NOTE: in order to use internal parallelism, adaptive or not, the user must activate it by specifying alglib::parallel in flags or global threading settings. ALGLIB for C++ must be compiled in the OS-aware mode. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolverfavorinternalparallelism(minlpsolverstate &state, const xparams _xparams = alglib::xdefault);
minlpsolveriteration function/************************************************************************* This function provides reverse communication interface Reverse communication interface is not documented or recommended to use. See below for functions which provide better documented API *************************************************************************/bool minlpsolveriteration(minlpsolverstate &state, const xparams _xparams = alglib::xdefault);
minlpsolvernoadaptiveinternalparallelism function/************************************************************************* This function controls adaptive internal parallelism, i.e. algorithm used by the solver to adaptively decide whether parallel acceleration of solver's internal calculations (B&B code, SQP, parallel linear algebra) should be actually used or not. This function tells the solver to do calculations exactly as prescribed by the user: in the parallel mode when alglib::parallel flag is passed, in the single-threaded mode otherwise. The solver does not analyze actual running times to decide whether parallelism is justified or not. NOTE: the internal parallelism is distinct from the callback parallelism. The former is the ability to utilize parallelism to speed-up solvers own internal calculations, while the latter is the ability to perform several callback evaluations at once. Aside from performance considerations, the internal parallelism is entirely transparent to the user. The callback parallelism requries the user to write a thread-safe, reentrant callback. NOTE: in order to use internal parallelism, adaptive or not, the user must activate it by specifying alglib::parallel in flags or global threading settings. ALGLIB for C++ must be compiled in the OS-aware mode. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolvernoadaptiveinternalparallelism(minlpsolverstate &state, const xparams _xparams = alglib::xdefault);
minlpsolveroptimize function/************************************************************************* This family of functions is used to start iterations of nonlinear optimizer These functions accept following parameters: state - algorithm state fvec - callback which calculates function vector fi[] at given point x jac - callback which calculates function vector fi[] and Jacobian jac at given point x sjac - callback which calculates function vector fi[] and sparse Jacobian sjac at given point x rep - optional callback which is called after each iteration can be NULL ptr - optional pointer which is passed to func/grad/hess/jac/rep can be NULL -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolveroptimize(minlpsolverstate &state, void (*fvec)(const real_1d_array &x, real_1d_array &fi, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault); void minlpsolveroptimize(minlpsolverstate &state, void (*jac)(const real_1d_array &x, real_1d_array &fi, real_2d_array &jac, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault); void minlpsolveroptimize(minlpsolverstate &state, void (*sjac)(const real_1d_array &x, real_1d_array &fi, sparsematrix &s, void *ptr), void (*rep)(const real_1d_array &x, double func, void *ptr) = NULL, void *ptr = NULL, const xparams _xparams = alglib::xdefault);
minlpsolverrestartfrom function/************************************************************************* This subroutine restarts algorithm from new point. All optimization parameters (including constraints) are left unchanged. This function allows to solve multiple optimization problems (which must have same number of dimensions) without object reallocation penalty. INPUT PARAMETERS: State - structure previously allocated with MINLPSolverCreate call. X - new starting point. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minlpsolverrestartfrom(minlpsolverstate &state, const real_1d_array &x, const xparams _xparams = alglib::xdefault);
minlpsolverresults function/************************************************************************* MINLPSolver results: the solution found, completion codes and additional information. INPUT PARAMETERS: Solver - solver OUTPUT PARAMETERS: X - array[N], solution Rep - optimization report, contains information about completion code, constraint violation at the solution and so on. rep.f contains objective value at the solution. You should check rep.terminationtype in order to distinguish successful termination from unsuccessful one. More information about fields of this structure can be found in the comments on the minlpsolverreport datatype. -- ALGLIB -- Copyright 18.01.2024 by Bochkanov Sergey *************************************************************************/void minlpsolverresults(const minlpsolverstate &state, real_1d_array &x, minlpsolverreport &rep, const xparams _xparams = alglib::xdefault);
minlpsolverresultsbuf function/************************************************************************* NLC results Buffered implementation of MINLPSolverResults() which uses pre-allocated buffer to store X[]. If buffer size is too small, it resizes buffer. It is intended to be used in the inner cycles of performance critical algorithms where array reallocation penalty is too large to be ignored. -- ALGLIB -- Copyright 28.11.2010 by Bochkanov Sergey *************************************************************************/void minlpsolverresultsbuf(const minlpsolverstate &state, real_1d_array &x, minlpsolverreport &rep, const xparams _xparams = alglib::xdefault);
minlpsolversetalgobbsync function/************************************************************************* This function tell the solver to use BBSYNC (Branch&Bound with Synchronous processing) mixed-integer nonlinear programming algorithm. The BBSYNC algorithm is an NLP-based branch-and-bound method with integral and spatial splits, supporting both convex and nonconvex problems. The algorithm combines parallelism support with deterministic behavior (i.e. the same branching decisions are performed with every parallel run). Non-convex (multiextremal) problems can be solved with multiple restarts from random points, which are activated by minlpsolversetmultistarts() IMPORTANT: contrary to the popular misconception, MINLP is not easily parallelizable. B&B trees often have profiles unsuitable for parallel processing (too short and/or too linear). Spatial or integral splits add some limited degree of parallelism (up to 2x in the very best case), but in practice it often results in just a 1.5x speed-up at best due to imbalanced leaf processing times. Furthermore, determinism is always at odds with efficiency. Achieving good parallel speed-up requires some amount of tuning and having a 2x-3x speed-up is already a good result. Only difficult long-running problems (here 'difficult' means that the value of rep.ntreenodes is at least several larger than the variables count) have good parallelism properties. On the other hand, setups using multiple random restarts are obviously highly parallelizable. IMPORTANT: the commercial edition of ALGLIB can accelerate factorization phase of this function (this phase takes significant amounts of time when solving large problems) by using SIMD intrinsics or a performance backend library (Intel PARDISO or another platform-specific sparse factorization library). Specific speed-up due to performance backend usage heavily depends on the sparsity pattern of constraints. For some problem types performance backends provide great speed-up. For other ones, ALGLIB's own sparse factorization code is the preferred option. See the ALGLIB Reference Manual for more information on how to activate parallelism and backend support. INPUT PARAMETERS: State - structure that stores algorithm state GroupSize - >=1, group size. Up to GroupSize tree nodes can be processed in the parallel manner. Increasing this parameter makes the solver less efficient serially (it always tries to fill the batch with nodes, even if there is a chance that most of them will be discarded later), but increases its parallel potential. Parallel speed-up comes from two sources: * callback parallelism (several objective values are computed concurrently), which is significant for problems with callbacks that take more than 1ms per evaluation * internal parallelism, i.e. ability to do parallel sparse matrix factorization and other solver- related tasks By default, the solver runs serially even for GroupSize>1. Both kinds of parallelism have to be activated by the user, see ALGLIB Reference Manual for more information. Recommended value, depending on callback cost and matrix factorization overhead, can be: * 1 for 'easy' problems with cheap callbacks and small dimensions; also for problems with nearly linear B&B trees. * 2-3 for problems with sufficiently costly callbacks (or sufficiently high linear algebra overhead) that it makes sense to utilize limited parallelism. * cores count - for difficult problems with deep and wide B&B trees and sufficiently costly callbacks (or sufficiently high linear algebra overhead). NOTES: DETERMINISM Running with fixed GroupSize generally produces same results independently of whether parallelism is used or not. Changing GroupSize parameter may change results in the following ways: * for problems that are solved to optimality but have multiple solutions, different values of this parameter may result in different solutions being returned (but still with the same objective value) * while operating close to exhausting budget (either timeout or iterations limit), different GroupSize values may result in different outcomes: a solution being found, or budget being exhausted * finally, on difficult problems that are too hard to solve to optimality but still allow finding primal feasible solutions changing GroupSize may result in different primal feasible solutions being returned. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetalgobbsync(minlpsolverstate &state, const ae_int_t groupsize, const xparams _xparams = alglib::xdefault);
Examples: [1]
minlpsolversetalgomivns function/************************************************************************* This function tell the solver to use MIVNS (Mixed-Integer Variable Neighborhood Search) solver for derivative-free mixed-integer nonlinear programming with expensive objective/constraints and non-relaxable integer variables. The solver is intended for moderately-sized problems, typically with tens of variables. The algorithm has the following features: * it supports all-integer and mixed-integer problems with box, linear and nonlinear equality and inequality constraints * it makes no assumptions about problem convexity * it does not require derivative information. Although it still assumes that objective/constraints are smooth wrt continuous variables, no such assumptions are made regarding dependence on integer variables. * it efficiently uses limited computational budget and scales well with larger budgets * it does not evaluate objective/constraints at points violating integrality * it also respects linear constraints in all intermediate points NOTE: In particular, if your task uses integrality+sum-to-one set of constraints to encode multiple choice options (e.g. [1,0,0], [0,1,0] or [0,0,1]), you can be sure that the algorithm will not ask for an objective value at a point with fractional values like [0.1,0.5,0.4] or at one that is not a correct one-hot encoded value (e.g. [1,1,0] which has two variables set to 1). The algorithm is intended for low-to-medium accuracy solution of otherwise intractable problems with expensive objective/constraints. It can solve any MINLP problem; however, it is optimized for the following problem classes: * limited variable count * expensive objective/constraints * nonrelaxable integer variables * no derivative information * problems where changes in integer variables lead to structural changes in the entire system. Speaking in other words, on problems where each integer variable acts as an on/off or "choice" switch that completely rewires the model - turning constraints, variables, or whole sub-systems on or off INPUT PARAMETERS: State - structure that stores algorithm state Budget - optimization budget (function evaluations). The solver will not stop immediately after reaching Budget evaluations, but will stop shortly after that (usually within 2N+1 evaluations). Zero value means no limit. MaxNeighborhood - stopping condition for the solver. The algorithm will stop as soon as there are no points better than the current candidate in a neighborhood whose size is equal to or exceeds MaxNeighborhood. Zero means no stopping condition. Recommended neighborhood size is proportional to the difference between integral variables count NI and the number of linear equality constraints on integral variables L (such constraints effectively reduce problem dimensionality). The very minimal value for binary problems is NI-L, which means that the solution can not be improved by flipping one of variables between 0 and 1. The very minimal value for non-binary integral vars is twice as much (because now each point has two neighbors per variable). However, such minimal values often result in an early termination. It is recommended to set this parameter to 5*N or 10*N (ignoring LI) and to test how it behaves on your problem. BatchSize >=1, recommended batch size for neighborhood exploration. Up to BatchSize nodes will be evaluated at any moment, thus up to BatchSize objective evaluations can be performed in parallel. Increasing this parameter makes the solver slightly less efficient serially (it always tries to fill the batch with nodes, even if there is a chance that most of them will be discarded later), but greatly increases its parallel potential. Recommended values depend on the cores count and on the limitations of the objective/constraints callback: * 1 for serial execution, callback that can not be called from multiple threads, or highly parallelized expensive callback that keeps all cores occupied * small fixed value like 5 or 10, if you need reproducible behavior independent from the cores count * CORESCOUNT, 2*CORESCOUNT or some other multiple of CORESCOUNT, if you want to utilize parallelism to the maximum extent Parallel speed-up comes from two sources: * callback parallelism (several objective values are computed concurrently), which is significant for problems with callbacks that take more than 1ms per evaluation * internal parallelism, i.e. ability to do parallel sparse matrix factorization and other solver- related tasks By default, the solver runs serially even for GroupSize>1. Both kinds of parallelism have to be activated by the user, see ALGLIB Reference Manual for more information. NOTES: if no stopping criteria is specified (unlimited budget, no timeout, no neighborhood size limit), then the solver will run until enumerating all integer solutions. ===== ALGORITHM DESCRIPTION ============================================== A simplified description for an all-integer algorithm, omitting stopping criteria and various checks: MIVNS (ALL-INTEGER): 1. Input: initial integral point, may be infeasible wrt nonlinear constraints, but is feasible wrt linear ones. Enforce linear feasibility, if needed. 2. Generate initial neighborhood around the current point that is equal to the point itself. The point is marked as explored. 3. Scan neighborhood for a better point (one that is less infeasible or has lower objective); if one is found, make it current and goto #2 4. Scan neighborhood for an unexplored point (one with no objective computed). If one if found, compute objective, mark the point as explored, goto #3 5. If there are no unexplored or better points in the neighborhood, expand it: find a point that was not used for expansion, compute up to 2N its nearest integral neighbors, add them to the neighborhood and mark as unexplored. Goto #3. NOTE: A nearest integral neighbor is a nearest point that differs at least by +1 or -1 in one of integral variables and that is feasible with respect to box and linear constraints (ignoring nonlinear ones). For problems with difficult constraint sets integral neighbors are found by solving MIQP subproblems. The algorithm above systematically scans neighborhood of a point until either better point is found, an entire integer grid is enumerated, or one of stopping conditions is met. A mixed-integer version of the algorithm is more complex: * it still sees optimization space as a set of integer nodes, each node having a subspace of continuous variables associated with it * after starting to explore a node, the algorithm runs an RBF surrogate- based subsolver for the node. It manages a dedicated subsolver for each node in a neighborhood and adaptively divides its computational budget between subsolvers, switching to a node as soon as its subsolver shows better results than its competitors. * the algorithm remembers all previously evaluated points and reuses them as much as possible ===== ALGORITHM SCALING WITH VARIABLES COUNT N =========================== A 'neighborhood scan' is a minimum number of function evaluations needed to perform at least minimal evaluation of the immediate neighborhood. For an N-dimensional problem with NI integer variables and NF continuous ones we have ~NI nodes in an immediate neighborhood, and each node needs ~NF evalutations to build at least linear model of the objective. Thus, a MIVNS neighborhood scan will need about NI*NF=NI*(N-NI)=NF*(N-NF) objective evaluations. It is important to note that MIVNS does not share information between nodes because it assumes that objective landscape can drastically change when jumping from node to node. That's why we need NI*NF instead of NI+NF objective values. In practice, when started not too far away from the minimum, we can expect to get some improvement in 5-10 scans, and to get significant progress in 50-100 scans. For problems with NF being small or NI being small we have scan cost being proportional to variables count N, which allows us to achieve good progress using between 5N and 100N objective values. However, when both NI and NF are close to N/2, a scan needs ~N^2 objective evaluations, which results in a much worse scaling behavior. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetalgomivns(minlpsolverstate &state, const ae_int_t budget, const ae_int_t maxneighborhood, const ae_int_t batchsize, const xparams _xparams = alglib::xdefault);
minlpsolversetbbsyncprofilelargetree function/************************************************************************* This function sets BBSYNC profile to "large tree". It means that we expect our problem to have a large B&B tree with much more than NInt (the integer variables count) nodes. However, we expect it to be solvable within our computational budget (i.e. that we are able to explore the entire B&B tree). BBSYNC solver will run with heuristics that are costly to power-up, but greatly improve performance on long distances: * reliability branching is used BBSYNC will not use heuristics that increase chance of finding good solutions early at the cost of increasing total time to prove optimality. INPUT PARAMETERS: State - structure that stores algorithm state -- ALGLIB -- Copyright 01.12.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetbbsyncprofilelargetree(minlpsolverstate &state, const xparams _xparams = alglib::xdefault);
minlpsolversetbbsyncprofilesmalltree function/************************************************************************* This function sets BBSYNC profile to "small tree". It means that we expect our problem to have a shallow B&B tree with the number of nodes comparable to the integer variables count, or below. BBSYNC solver will run with simplified settings: * pseudocost branching is used INPUT PARAMETERS: State - structure that stores algorithm state -- ALGLIB -- Copyright 01.12.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetbbsyncprofilesmalltree(minlpsolverstate &state, const xparams _xparams = alglib::xdefault);
minlpsolversetbc function/************************************************************************* This function sets box constraints for the mixed integer optimizer. Box constraints are inactive by default. IMPORTANT: box constraints work in parallel with the integrality ones: * a variable marked as integral is considered having no bounds until minlpsolversetbc() is called * a variable with lower and upper bounds set is considered continuous until marked as integral with the minlpsolversetintkth() function. INPUT PARAMETERS: State - structure stores algorithm state BndL - lower bounds, array[N]. If some (all) variables are unbounded, you may specify a very small number or -INF, with the latter option being recommended. BndU - upper bounds, array[N]. If some (all) variables are unbounded, you may specify a very large number or +INF, with the latter option being recommended. NOTE 1: it is possible to specify BndL[i]=BndU[i]. In this case I-th variable will be "frozen" at X[i]=BndL[i]=BndU[i]. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetbc(minlpsolverstate &state, const real_1d_array &bndl, const real_1d_array &bndu, const xparams _xparams = alglib::xdefault);
minlpsolversetctol function/************************************************************************* This function sets tolerance for nonlinear constraints; points violating constraints by no more than CTol are considered feasible. Depending on the specific algorithm used, constraint violation may be checked against internally scaled/normalized constraints (some smooth solvers renormalize constraints in such a way that they have roughly unit gradient magnitudes) or against raw constraint values: * BBSYNC renormalizes constraints prior to comparing them with CTol * MIRBF-VNS checks violation against raw constraint values IMPORTANT: one should be careful when choosing tolerances and stopping criteria. A solver stops as soon as stopping criteria are triggered; a feasibility check is performed after that. If too loose stopping criteria are used, the solver may fail to enforce constraints with sufficient accuracy and fail to recognize solution as a feasible one. For example, stopping with EpsX=0.01 and checking CTol=0.000001 will almost surely result in problems. Ideally, CTol should be 1-2 orders of magnitude more relaxed than stopping criteria. INPUT PARAMETERS: State - structure stores algorithm state CTol - >0, tolerance. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetctol(minlpsolverstate &state, const double ctol, const xparams _xparams = alglib::xdefault);
minlpsolversetintkth function/************************************************************************* This function marks K-th variable as an integral one. Unless box constraints are set for the variable, it is unconstrained (i.e. can take positive or negative values). By default all variables are continuous. IMPORTANT: box constraints work in parallel with the integrality ones: * a variable marked as integral is considered having no bounds until minlpsolversetbc() is called * a variable with lower and upper bounds set is considered continuous until marked as integral with the minlpsolversetintkth() function. INPUT PARAMETERS: State - structure stores algorithm state K - 0<=K<N, variable index -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetintkth(minlpsolverstate &state, const ae_int_t k, const xparams _xparams = alglib::xdefault);
minlpsolversetlc2 function/************************************************************************* This function sets two-sided linear constraints AL <= A*x <= AU with a sparse constraining matrix A. Recommended for large-scale problems. This function overwrites linear (non-box) constraints set by previous calls (if such calls were made). INPUT PARAMETERS: State - structure previously allocated with minlpsolvercreate() call. A - sparse matrix with size [K,N] (exactly!). Each row of A represents one general linear constraint. A can be stored in any sparse storage format. AL, AU - lower and upper bounds, array[K]; * AL[i]=AU[i] => equality constraint Ai*x * AL[i]<AU[i] => two-sided constraint AL[i]<=Ai*x<=AU[i] * AL[i]=-INF => one-sided constraint Ai*x<=AU[i] * AU[i]=+INF => one-sided constraint AL[i]<=Ai*x * AL[i]=-INF, AU[i]=+INF => constraint is ignored K - number of equality/inequality constraints, K>=0. If K=0 is specified, A, AL, AU are ignored. -- ALGLIB -- Copyright 15.04.2024 by Bochkanov Sergey *************************************************************************/void minlpsolversetlc2(minlpsolverstate &state, const sparsematrix &a, const real_1d_array &al, const real_1d_array &au, const ae_int_t k, const xparams _xparams = alglib::xdefault);
minlpsolversetlc2dense function/************************************************************************* This function sets two-sided linear constraints AL <= A*x <= AU with dense constraint matrix A. INPUT PARAMETERS: State - structure previously allocated with minlpsolvercreate() call. A - linear constraints, array[K,N]. Each row of A represents one constraint. One-sided inequality constraints, two- sided inequality constraints, equality constraints are supported (see below) AL, AU - lower and upper bounds, array[K]; * AL[i]=AU[i] => equality constraint Ai*x * AL[i]<AU[i] => two-sided constraint AL[i]<=Ai*x<=AU[i] * AL[i]=-INF => one-sided constraint Ai*x<=AU[i] * AU[i]=+INF => one-sided constraint AL[i]<=Ai*x * AL[i]=-INF, AU[i]=+INF => constraint is ignored K - number of equality/inequality constraints, K>=0; if not given, inferred from sizes of A, AL, AU. -- ALGLIB -- Copyright 15.04.2024 by Bochkanov Sergey *************************************************************************/void minlpsolversetlc2dense(minlpsolverstate &state, const real_2d_array &a, const real_1d_array &al, const real_1d_array &au, const ae_int_t k, const xparams _xparams = alglib::xdefault); void minlpsolversetlc2dense(minlpsolverstate &state, const real_2d_array &a, const real_1d_array &al, const real_1d_array &au, const xparams _xparams = alglib::xdefault);
minlpsolversetlc2mixed function/************************************************************************* This function sets two-sided linear constraints AL <= A*x <= AU with a mixed constraining matrix A including a sparse part (first SparseK rows) and a dense part (last DenseK rows). Recommended for large-scale problems. This function overwrites linear (non-box) constraints set by previous calls (if such calls were made). This function may be useful if constraint matrix includes large number of both types of rows - dense and sparse. If you have just a few sparse rows, you may represent them in dense format without losing performance. Similarly, if you have just a few dense rows, you may store them in sparse format with almost same performance. INPUT PARAMETERS: State - structure previously allocated with minlpsolvercreate() call. SparseA - sparse matrix with size [K,N] (exactly!). Each row of A represents one general linear constraint. A can be stored in any sparse storage format. SparseK - number of sparse constraints, SparseK>=0 DenseA - linear constraints, array[K,N], set of dense constraints. Each row of A represents one general linear constraint. DenseK - number of dense constraints, DenseK>=0 AL, AU - lower and upper bounds, array[SparseK+DenseK], with former SparseK elements corresponding to sparse constraints, and latter DenseK elements corresponding to dense constraints; * AL[i]=AU[i] => equality constraint Ai*x * AL[i]<AU[i] => two-sided constraint AL[i]<=Ai*x<=AU[i] * AL[i]=-INF => one-sided constraint Ai*x<=AU[i] * AU[i]=+INF => one-sided constraint AL[i]<=Ai*x * AL[i]=-INF, AU[i]=+INF => constraint is ignored K - number of equality/inequality constraints, K>=0. If K=0 is specified, A, AL, AU are ignored. -- ALGLIB -- Copyright 15.04.2024 by Bochkanov Sergey *************************************************************************/void minlpsolversetlc2mixed(minlpsolverstate &state, const sparsematrix &sparsea, const ae_int_t ksparse, const real_2d_array &densea, const ae_int_t kdense, const real_1d_array &al, const real_1d_array &au, const xparams _xparams = alglib::xdefault);
minlpsolversetmultistarts function/************************************************************************* This function activates multiple random restarts (performed for each node, including root and child ones) that help to find global solutions to non- convex problems. This parameter is used by branch-and-bound solvers and is presently ignored by derivative-free solvers. INPUT PARAMETERS: State - structure that stores algorithm state NMultistarts - >=1, number of random restarts: * 1 means that no restarts performed, the solver assumes convexity * >=1 means that solver assumes non-convexity and performs fixed amount of random restarts -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetmultistarts(minlpsolverstate &state, const ae_int_t nmultistarts, const xparams _xparams = alglib::xdefault);
minlpsolversetnlc2 function/************************************************************************* This function sets two-sided nonlinear constraints for MINLP optimizer. In fact, this function sets only constraints COUNT and their BOUNDS. Constraints themselves (constraint functions) are passed to the MINLPSolverOptimize() method as callbacks. MINLPSolverOptimize() method accepts a user-defined vector function F[] and its Jacobian J[], where: * first element of F[] and first row of J[] correspond to the target * subsequent NNLC components of F[] (and rows of J[]) correspond to two- sided nonlinear constraints NL<=C(x)<=NU, where * NL[i]=NU[i] => I-th row is an equality constraint Ci(x)=NL * NL[i]<NU[i] => I-th tow is a two-sided constraint NL[i]<=Ci(x)<=NU[i] * NL[i]=-INF => I-th row is an one-sided constraint Ci(x)<=NU[i] * NU[i]=+INF => I-th row is an one-sided constraint NL[i]<=Ci(x) * NL[i]=-INF, NU[i]=+INF => constraint is ignored NOTE: you may combine nonlinear constraints with linear/boundary ones. If your problem has mixed constraints, you may explicitly specify some of them as linear or box ones. It helps optimizer to handle them more efficiently. INPUT PARAMETERS: State - structure previously allocated with MINLPSolverCreate call. NL - array[NNLC], lower bounds, can contain -INF NU - array[NNLC], lower bounds, can contain +INF NNLC - constraints count, NNLC>=0 NOTE 1: nonlinear constraints are satisfied only approximately! It is possible that the algorithm will evaluate the function outside of the feasible area! NOTE 2: algorithm scales variables according to the scale specified by MINLPSolverSetScale() function, so it can handle problems with badly scaled variables (as long as we KNOW their scales). However, there is no way to automatically scale nonlinear constraints. Inappropriate scaling of nonlinear constraints may ruin convergence. Solving problem with constraint "1000*G0(x)=0" is NOT the same as solving it with constraint "0.001*G0(x)=0". It means that YOU are the one who is responsible for the correct scaling of the nonlinear constraints Gi(x) and Hi(x). We recommend you to scale nonlinear constraints in such a way that the Jacobian rows have approximately unit magnitude (for problems with unit scale) or have magnitude approximately equal to 1/S[i] (where S is a scale set by MINLPSolverSetScale() function). -- ALGLIB -- Copyright 05.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetnlc2(minlpsolverstate &state, const real_1d_array &nl, const real_1d_array &nu, const ae_int_t nnlc, const xparams _xparams = alglib::xdefault); void minlpsolversetnlc2(minlpsolverstate &state, const real_1d_array &nl, const real_1d_array &nu, const xparams _xparams = alglib::xdefault);
minlpsolversetobjectivemaskdense function/************************************************************************* This function sets variable mask for the objective. A variable mask is a set of variables actually appearing in the objective. If you want to set variable mask for a nonlinear constraint, use addnlc2masked() or addnlc2maskeddense() to add a constraint together with a constraint-specific mask. Variable masks provide crucial information for derivative-free solvers, greatly accelerating surrogate model construction. This applies to both continuous and integral variables, with results for binary variables being more pronounced. Up to 2x improvement in convergence speed has been observed for sufficiently sparse MINLP problems. NOTE: In order to unleash the full potential of variable masking, it is important to provide masks for objective as well as all nonlinear constraints. Even partial information matters, i.e. if you are 100% sure that your black-box function does not depend on some variables, but unsure about other ones, mark surely irrelevant variables, and tell the solver that other ones may be relevant. NOTE: the solver is may behave unpredictably if some relevant variable is not included into the mask. Most likely it will fail to converge, although it sometimes possible to converge to solution even with incorrectly specified mask. NOTE: Masks are ignored by branch-and-bound-type solvers relying on analytic gradients. INPUT PARAMETERS: State - structure stores algorithm state ObjMask - array[N], I-th element is False if I-th variable is irrelevant. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetobjectivemaskdense(minlpsolverstate &state, const boolean_1d_array &objmask, const xparams _xparams = alglib::xdefault);
minlpsolversetpdgap function/************************************************************************* This function sets stopping condition for the branch-and-bound family of solvers: a solver must when when the gap between primal and dual bounds is less than PDGap. The solver computes relative gap, equal to |Fprim-Fdual|/max(|Fprim|,1). This parameter is ignored by other types of solvers, e.g. MIVNS. INPUT PARAMETERS: State - structure stores algorithm state PDGap - >=0, tolerance. Zero value means that some default value is automatically selected. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetpdgap(minlpsolverstate &state, const double pdgap, const xparams _xparams = alglib::xdefault);
minlpsolversetscale function/************************************************************************* This function sets scaling coefficients for the mixed integer optimizer. ALGLIB optimizers use scaling matrices to test stopping conditions (step size and gradient are scaled before comparison with tolerances). Scales are also used by the finite difference variant of the optimizer - the step along I-th axis is equal to DiffStep*S[I]. Finally, variable scales are used for preconditioning (i.e. to speed up the solver). The scale of the I-th variable is a translation invariant measure of: a) "how large" the variable is b) how large the step should be to make significant changes in the function INPUT PARAMETERS: State - structure stores algorithm state S - array[N], non-zero scaling coefficients S[i] may be negative, sign doesn't matter. -- ALGLIB -- Copyright 06.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetscale(minlpsolverstate &state, const real_1d_array &s, const xparams _xparams = alglib::xdefault);
minlpsolversetsubsolverepsf function/************************************************************************* This function tells MINLP solver to use an objective-based stopping condition for an underlying subsolver, i.e. to stop subsolver if relative change in objective between iterations is less than EpsF. Too tight EspF, as always, result in spending too much time in the solver. Zero value means that some default non-zero value will be used. Exact action of this condition as well as reaction to too relaxed EpsF depend on specific MINLP solver being used * BBSYNC. This condition controls SQP subsolver used to solve NLP (relaxed) subproblems arising during B&B tree search. Good values are typically between 1E-6 and 1E-7. Too relaxed values may result in subproblems being mistakenly fathomed (feasible solutions not identified), too large constraint violations, etc. * MIVNS. This condition controls RBF-based surrogate model subsolver used to handle continuous variables. It is ignored for integer-only problems. The subsolver stops if total objective change in last several (between 5 and 10) steps is less than EpsF. More than one step is used to check convergence because surrogate model-based solvers usually need more stringent stopping criteria than SQP. Good values are relatively high, between 0.01 and 0.0001, depending on a problem. The MIVNS solver is designed to gracefully handle large values of EpsF - it will stop early, but it won't compromise feasibility (it will try to reduce constraint violations below CTol) and will not drop promising integral nodes. INPUT PARAMETERS: State - solver structure EpsF - >0, stopping condition -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetsubsolverepsf(minlpsolverstate &state, const double epsf, const xparams _xparams = alglib::xdefault);
minlpsolversetsubsolverepsx function/************************************************************************* This function tells MINLP solver to use a step-based stopping condition for an underlying subsolver, i.e. to stop subsolver if typical step size becomes less than EpsX. Too tight EspX, as always, result in spending too much time in the solver. Zero value means that some default non-zero value will be used. Exact action of this condition as well as reaction to too relaxed EpsX depend on specific MINLP solver being used * BBSYNC. This condition controls SQP subsolver used to solve NLP (relaxed) subproblems arising during B&B tree search. Good values are typically between 1E-6 and 1E-7. Too relaxed values may result in subproblems being mistakenly fathomed (feasible solutions not identified), too large constraint violations, etc. * MIVNS. This condition controls RBF-based surrogate model subsolver used to handle continuous variables. It is ignored for integer-only problems. The subsolver stops if trust radius for a surrogate model optimizer becomes less than EpsX. Good values are relatively high, between 0.01 and 0.0001, depending on a problem. The MIVNS solver is designed to gracefully handle large values of EpsX - it will stop early, but it won't compromise feasibility (it will try to reduce constraint violations below CTol) and will not drop promising integral nodes. INPUT PARAMETERS: State - solver structure EpsX - >=0, stopping condition. Zero value means that some default value will be used. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversetsubsolverepsx(minlpsolverstate &state, const double epsx, const xparams _xparams = alglib::xdefault);
minlpsolversettimeout function/************************************************************************* This function activates timeout feature. The solver finishes after running for a specified amount of time (in seconds, fractions can be used) with the best point so far. Depending on the situation, the following completion codes can be reported in rep.terminationtype: * -33 (failure), if timed out without finding a feasible point * 5 (partial success), if timed out after finding at least one feasible point The solver does not stop immediately after timeout was triggered because it needs some time for underlying subsolvers to react to timeout signal. Generally, about one additional subsolver iteration (which is usually far less than one B&B split) will be performed prior to stopping. INPUT PARAMETERS: State - structure that stores algorithm state Timeout - >=0, timeout in seconds (floating point number): * 0 means no timeout * >=0 means stopping after specified number of seconds. -- ALGLIB -- Copyright 01.01.2025 by Bochkanov Sergey *************************************************************************/void minlpsolversettimeout(minlpsolverstate &state, const double timeout, const xparams _xparams = alglib::xdefault);
#include "stdafx.h" #include <stdlib.h> #include <stdio.h> #include <math.h> #include "minlp.h" using namespace alglib; void minlp_cluster_jac(co