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

1 Introduction

1.1 What is ALGLIB

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.

1.2 ALGLIB license

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.

1.3 Documentation license

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.

1.4 Reference Manual and User Guide

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.

1.5 Acknowledgements

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.

2 ALGLIB structure

2.1 Packages

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.

2.2 Subpackages

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.

2.3 Open Source and Commercial versions

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.

3 Compatibility

3.1 CPU

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.

3.2 OS

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.

3.3 Compiler

ALGLIB is compatible with any C++ compiler which:

All modern mainstream compilers (MSVC, GCC, Clang, ICC) satisfy these requirements. Most specialized compilers for DSPs also satisfy them.

3.4 Optimization settings

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:

4 Compiling ALGLIB

4.1 Adding to your project

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.

4.2 Configuring for your compiler

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:

In most cases, it is enough. But if anything goes wrong, you have several options:

4.3 Utilizing SIMD

4.3.1 Overview

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.

4.3.2 Achieving best performance

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:

The 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:

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.

4.3.3 Achieving best portability

If one needs a SIMD-capable application with portability guarantees, one has to:

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.

4.3.4 Disabling SIMD instruction sets at compile time

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:

4.4 Utilizing SMP

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.

4.5 Examples (free and commercial editions)

4.5.1 Introduction

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).

4.5.2 Compiling under Windows

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!

4.5.3 Compiling under Linux

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!

5 Using ALGLIB

5.1 Thread-safety

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!

5.2 Global definitions

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.

5.3 Datatypes

ALGLIB (ap.h header) defines several "basic" datatypes (types which are used by all packages) and many package-specific datatypes. "Basic" datatypes are:

Package-specific datatypes are classes which can be divided into two distinct groups:

5.4 Constants

The most important constants (defined in the ap.h header) from ALGLIB namespace are:

5.5 Functions

The most important "basic" functions from ALGLIB namespace (ap.h header) are:

5.6 Working with vectors and matrices

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());

5.7 Using functions: 'expert' and 'friendly' interfaces

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

5.8 Handling errors

ALGLIB uses two error handling strategies:

What is actually done depends on function being used and error being reported:

  1. if function returns some error code and has corresponding value for this kind of error, ALLGIB returns error code
  2. if function does not return error code (or returns error code, but there is no code for error being reported), ALGLIB throws 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.

5.9 Working with Level 1 BLAS functions

ALGLIB (ap.h header) includes following Level 1 BLAS functions:

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);

5.10 Reading data from CSV files

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.

6 Working with commercial version

6.1 Benefits of commercial version

Commercial version of ALGLIB for C++ features four important improvements over open source one:

6.2 Working with SIMD support (Intel/AMD users)

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.

6.3 Using multithreading

6.3.1 General information

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.

6.3.2 Compiling ALGLIB in the multithreaded mode

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.

6.3.3 Two kinds of parallelism

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.

6.3.4 Activating parallelism

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:

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.

6.3.5 Controlling cores count

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:

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.

6.3.6 More on parallel callbacks

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.

6.3.7 SMT/hyper-threading issues

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.

6.4 Linking with precompiled performance backends

6.4.1 Introduction

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.

6.4.2 Using precompiled performance backends

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:

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:

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.

6.4.3 Performance backend: mklmini

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:

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:

6.4.4 Performance backend: mklfull

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:

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:

6.5 Linking with performance backends installed on your system

6.5.1 Using your own installation of Intel MKL

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.

7 Advanced topics

7.1 Using Red Zones to find memory access violations

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).

7.2 Replacing stdlib rand() as an entropy source with OpenSSL implementation

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:

7.3 Exception-free mode

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:

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:

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":

7.4 Partial compilation

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:

7.5 Testing ALGLIB

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

  1. compile one of these files (test_c.cpp, test_i.cpp or test_x.cpp) along with the rest of the library
  2. launch executable you will get. It may take from several seconds (interface tests) to several minutes (computational tests) to get final results

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 ALGLIB packages and subpackages

8.1 AlglibMisc package

hqrnd High quality random numbers generator
nearestneighbor Nearest neighbor search: approximate and exact
xdebug Debug functions to test ALGLIB interface generator
 

8.2 DataAnalysis package

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 DiffEquations package

odesolver Ordinary differential equation solver
 

8.4 FastTransforms package

conv Fast real/complex convolution
corr Fast real/complex cross-correlation
fft Real/complex FFT
fht Real Fast Hartley Transform
 

8.5 Integration package

autogk Adaptive 1-dimensional integration
gkq Gauss-Kronrod quadrature generator
gq Gaussian quadrature generator
 

8.6 Interpolation package

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 LinAlg package

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 MINLP package

minlpsolvers Mixed-integer nonlinear programming solver (structured and black-box problems)
 

8.9 Optimization package

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 Solvers package

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 SpecialFunctions package

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 Statistics package

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
 
cmatrixcopy
cmatrixgemm
cmatrixherk
cmatrixlefttrsm
cmatrixmv
cmatrixrank1
cmatrixrighttrsm
cmatrixsyrk
cmatrixtranspose
rmatrixcopy
rmatrixenforcesymmetricity
rmatrixgemm
rmatrixgemv
rmatrixgencopy
rmatrixger
rmatrixlefttrsm
rmatrixmv
rmatrixrank1
rmatrixrighttrsm
rmatrixsymv
rmatrixsyrk
rmatrixsyvmv
rmatrixtranspose
rmatrixtrsv
rvectorcopy
ablas_d_gemm Matrix multiplication (single-threaded)
ablas_d_syrk Symmetric rank-K update (single-threaded)
/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* *************************************************************************/
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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* *************************************************************************/
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);
/************************************************************************* 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]  

/************************************************************************* *************************************************************************/
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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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;
}

airy
/************************************************************************* 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);
autogkreport
autogkstate
autogkintegrate
autogkiteration
autogkresults
autogksingular
autogksmooth
autogksmoothw
autogk_d1 Integrating f=exp(x) by adaptive integrator
/************************************************************************* 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; };
/************************************************************************* 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(); };
/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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;
}

cov2
covm
covm2
pearsoncorr2
pearsoncorrelation
pearsoncorrm
pearsoncorrm2
rankdata
rankdatacentered
sampleadev
samplekurtosis
samplemean
samplemedian
samplemoments
samplepercentile
sampleskewness
samplevariance
spearmancorr2
spearmancorrm
spearmancorrm2
spearmanrankcorrelation
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
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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;
}

dsoptimalsplit2
dsoptimalsplit2fast
/************************************************************************* 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);
/************************************************************************* 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);
rmatrixbdsvd
/************************************************************************* 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);
besseli0
besseli1
besselj0
besselj1
besseljn
besselk0
besselk1
besselkn
bessely0
bessely1
besselyn
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
beta
/************************************************************************* 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);
binomialcdistribution
binomialdistribution
invbinomialdistribution
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
chebyshevcalculate
chebyshevcoefficients
chebyshevsum
fromchebyshev
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
chisquarecdistribution
chisquaredistribution
invchisquaredistribution
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
ahcreport
clusterizerstate
kmeansreport
clusterizercreate
clusterizergetdistances
clusterizergetkclusters
clusterizerrunahc
clusterizerrunkmeans
clusterizerseparatedbycorr
clusterizerseparatedbydist
clusterizersetahcalgo
clusterizersetdistances
clusterizersetkmeansinit
clusterizersetkmeanslimits
clusterizersetpoints
clusterizersetseed
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
/************************************************************************* 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; };
/************************************************************************* 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(); };
/************************************************************************* 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; };
/************************************************************************* 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);

Examples:   [1]  [2]  [3]  [4]  [5]  

/************************************************************************* 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);
/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  [3]  [4]  [5]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);

Examples:   [1]  [2]  [3]  [4]  [5]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);

Examples:   [1]  [2]  [3]  [4]  [5]  

/************************************************************************* 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;
}

convc1d
convc1dbuf
convc1dcircular
convc1dcircularbuf
convc1dcircularinv
convc1dcircularinvbuf
convc1dinv
convc1dinvbuf
convr1d
convr1dbuf
convr1dcircular
convr1dcircularbuf
convr1dcircularinv
convr1dcircularinvbuf
convr1dinv
convr1dinvbuf
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
corrc1d
corrc1dbuf
corrc1dcircular
corrc1dcircularbuf
corrr1d
corrr1dbuf
corrr1dcircular
corrr1dcircularbuf
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
pearsoncorrelationsignificance
spearmanrankcorrelationsignificance
/************************************************************************* 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);
/************************************************************************* 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);
kmeansgenerate
/************************************************************************* 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);
dawsonintegral
/************************************************************************* 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);
decisionforest
decisionforestbuffer
decisionforestbuilder
dfreport
dfavgce
dfavgerror
dfavgrelerror
dfbinarycompression
dfbuilderbuildrandomforest
dfbuildercreate
dfbuildergetprogress
dfbuilderpeekprogress
dfbuildersetdataset
dfbuildersetimportancenone
dfbuildersetimportanceoobgini
dfbuildersetimportancepermutation
dfbuildersetimportancetrngini
dfbuildersetrdfalgo
dfbuildersetrdfsplitstrength
dfbuildersetrndvars
dfbuildersetrndvarsauto
dfbuildersetrndvarsratio
dfbuildersetseed
dfbuildersetsubsampleratio
dfbuildrandomdecisionforest
dfbuildrandomdecisionforestx1
dfclassify
dfcreatebuffer
dfprocess
dfprocess0
dfprocessi
dfrelclserror
dfrmserror
dfserialize
dftsprocess
dfunserialize
randomforest_cls Simple classification with random forests
randomforest_reg Simple regression with decision forest
/************************************************************************* Decision forest (random forest) model. *************************************************************************/
class decisionforest { public: decisionforest(); decisionforest(const decisionforest &rhs); decisionforest& operator=(const decisionforest &rhs); virtual ~decisionforest(); };
/************************************************************************* 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(); };
/************************************************************************* 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(); };
/************************************************************************* 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; };
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);
/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);
/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* '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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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;
}

densesolverlsreport
densesolverreport
cmatrixlusolve
cmatrixlusolvefast
cmatrixlusolvem
cmatrixlusolvemfast
cmatrixmixedsolve
cmatrixmixedsolvem
cmatrixsolve
cmatrixsolvefast
cmatrixsolvem
cmatrixsolvemfast
hpdmatrixcholeskysolve
hpdmatrixcholeskysolvefast
hpdmatrixcholeskysolvem
hpdmatrixcholeskysolvemfast
hpdmatrixsolve
hpdmatrixsolvefast
hpdmatrixsolvem
hpdmatrixsolvemfast
rmatrixlusolve
rmatrixlusolvefast
rmatrixlusolvem
rmatrixlusolvemfast
rmatrixmixedsolve
rmatrixmixedsolvem
rmatrixsolve
rmatrixsolvefast
rmatrixsolvels
rmatrixsolvem
rmatrixsolvemfast
spdmatrixcholeskysolve
spdmatrixcholeskysolvefast
spdmatrixcholeskysolvem
spdmatrixcholeskysolvemfast
spdmatrixsolve
spdmatrixsolvefast
spdmatrixsolvem
spdmatrixsolvemfast
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
/************************************************************************* *************************************************************************/
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; };
/************************************************************************* *************************************************************************/
class densesolverreport { public: densesolverreport(); densesolverreport(const densesolverreport &rhs); densesolverreport& operator=(const densesolverreport &rhs); virtual ~densesolverreport(); ae_int_t terminationtype; double r1; double rinf; };
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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;
}

sparselusolve
sparsesolve
sparsesolvelsreg
sparsespdcholeskysolve
sparsespdsolve
sparsespdsolvesks
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
/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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);
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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;
}

ellipticintegrale
ellipticintegralk
ellipticintegralkhighprecision
incompleteellipticintegrale
incompleteellipticintegralk
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
eigsubspacereport
eigsubspacestate
eigsubspacecreate
eigsubspacecreatebuf
eigsubspaceooccontinue
eigsubspaceoocgetrequestdata
eigsubspaceoocgetrequestinfo
eigsubspaceoocsendresult
eigsubspaceoocstart
eigsubspaceoocstop
eigsubspacesetcond
eigsubspacesetwarmstart
eigsubspacesolvedenses
eigsubspacesolvesparses
hmatrixevd
hmatrixevdi
hmatrixevdr
rmatrixevd
smatrixevd
smatrixevdi
smatrixevdr
smatrixtdevd
smatrixtdevdi
smatrixtdevdr
/************************************************************************* 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; };
/************************************************************************* 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(); };
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
exponentialintegralei
exponentialintegralen
/************************************************************************* 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);
/************************************************************************* 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);
fcdistribution
fdistribution
invfdistribution
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
fftc1d
fftc1dinv
fftr1d
fftr1dbuf
fftr1dinv
fftr1dinvbuf
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
/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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);
/************************************************************************* 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);

Examples:   [1]  [2]  

/************************************************************************* 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;
}

fhtr1d
fhtr1dinv
/************************************************************************* 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);
/************************************************************************* 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);
filterema
filterlrma
filtersma
filters_d_ema EMA(alpha) filter
filters_d_lrma LRMA(k) filter
filters_d_sma SMA(k) filter
/************************************************************************* 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]  

/************************************************************************* 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]  

/************************************************************************* 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;
}

fitspherels
fitspheremc
fitspheremi
fitspheremz
fitspherex
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
/************************************************************************* 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);
fresnelintegral
/************************************************************************* 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);
gammafunction
lngamma
/************************************************************************* 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);
/************************************************************************* 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);
gkqgenerategaussjacobi
gkqgenerategausslegendre
gkqgeneraterec
gkqlegendrecalc
gkqlegendretbl