/************************************************************************* Dense solver. Same as RMatrixLUSolve(), but for HPD matrices represented by their Cholesky decomposition. 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. 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 Info - same as in RMatrixSolve Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void hpdmatrixcholeskysolve(complex[,] cha, int n, bool isupper, complex[] b, out int info, out densesolverreport rep, out complex[] x) { info = 0; rep = new densesolverreport(); x = new complex[0]; densesolver.hpdmatrixcholeskysolve(cha, n, isupper, b, ref info, rep.innerobj, ref x); return; }
/************************************************************************* 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 Info - same as in RMatrixSolveM Rep - same as in RMatrixSolveM X - same as in RMatrixSolveM -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void cmatrixmixedsolve(complex[,] a, complex[,] lua, int[] p, int n, complex[] b, out int info, out densesolverreport rep, out complex[] x) { info = 0; rep = new densesolverreport(); x = new complex[0]; densesolver.cmatrixmixedsolve(a, lua, p, n, b, ref info, rep.innerobj, ref x); return; }
public static void smp_spdmatrixsolve(double[,] a, int n, bool isupper, double[] b, out int info, out densesolverreport rep, out double[] x) { info = 0; rep = new densesolverreport(); x = new double[0]; densesolver._pexec_spdmatrixsolve(a, n, isupper, b, ref info, rep.innerobj, ref x); return; }
/************************************************************************* Internal LU solver -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ private static void cmatrixlusolveinternal(complex[,] lua, int[] p, double scalea, int n, complex[,] a, bool havea, complex[,] b, int m, ref int info, densesolverreport rep, ref complex[,] x) { int i = 0; int j = 0; int k = 0; int rfs = 0; int nrfs = 0; complex[] xc = new complex[0]; complex[] y = new complex[0]; complex[] bc = new complex[0]; complex[] xa = new complex[0]; complex[] xb = new complex[0]; complex[] tx = new complex[0]; double[] tmpbuf = new double[0]; complex v = 0; double verr = 0; double mxb = 0; double scaleright = 0; bool smallerr = new bool(); bool terminatenexttime = new bool(); int i_ = 0; info = 0; x = new complex[0,0]; alglib.ap.assert((double)(scalea)>(double)(0)); // // prepare: check inputs, allocate space... // if( n<=0 || m<=0 ) { info = -1; return; } for(i=0; i<=n-1; i++) { if( p[i]>n-1 || p[i]<i ) { info = -1; return; } } x = new complex[n, m]; y = new complex[n]; xc = new complex[n]; bc = new complex[n]; tx = new complex[n]; xa = new complex[n+1]; xb = new complex[n+1]; tmpbuf = new double[2*n+2]; // // estimate condition number, test for near singularity // rep.r1 = rcond.cmatrixlurcond1(lua, n); rep.rinf = rcond.cmatrixlurcondinf(lua, n); if( (double)(rep.r1)<(double)(rcond.rcondthreshold()) || (double)(rep.rinf)<(double)(rcond.rcondthreshold()) ) { for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { x[i,j] = 0; } } rep.r1 = 0; rep.rinf = 0; info = -3; return; } info = 1; // // solve // for(k=0; k<=m-1; k++) { // // copy B to contiguous storage // for(i_=0; i_<=n-1;i_++) { bc[i_] = b[i_,k]; } // // Scale right part: // * MX stores max(|Bi|) // * ScaleRight stores actual scaling applied to B when solving systems // it is chosen to make |scaleRight*b| close to 1. // mxb = 0; for(i=0; i<=n-1; i++) { mxb = Math.Max(mxb, math.abscomplex(bc[i])); } if( (double)(mxb)==(double)(0) ) { mxb = 1; } scaleright = 1/mxb; // // First, non-iterative part of solution process. // We use separate code for this task because // XDot is quite slow and we want to save time. // for(i_=0; i_<=n-1;i_++) { xc[i_] = scaleright*bc[i_]; } cbasiclusolve(lua, p, scalea, n, ref xc, ref tx); // // Iterative refinement of xc: // * calculate r = bc-A*xc using extra-precise dot product // * solve A*y = r // * update x:=x+r // // This cycle is executed until one of two things happens: // 1. maximum number of iterations reached // 2. last iteration decreased error to the lower limit // if( havea ) { nrfs = densesolverrfsmax(n, rep.r1, rep.rinf); terminatenexttime = false; for(rfs=0; rfs<=nrfs-1; rfs++) { if( terminatenexttime ) { break; } // // generate right part // smallerr = true; for(i_=0; i_<=n-1;i_++) { xb[i_] = xc[i_]; } for(i=0; i<=n-1; i++) { for(i_=0; i_<=n-1;i_++) { xa[i_] = scalea*a[i,i_]; } xa[n] = -1; xb[n] = scaleright*bc[i]; xblas.xcdot(xa, xb, n+1, ref tmpbuf, ref v, ref verr); y[i] = -v; smallerr = smallerr && (double)(math.abscomplex(v))<(double)(4*verr); } if( smallerr ) { terminatenexttime = true; } // // solve and update // cbasiclusolve(lua, p, scalea, n, ref y, ref tx); for(i_=0; i_<=n-1;i_++) { xc[i_] = xc[i_] + y[i_]; } } } // // Store xc. // Post-scale result. // v = scalea*mxb; for(i_=0; i_<=n-1;i_++) { x[i_,k] = v*xc[i_]; } } }
public static void smp_cmatrixsolve(complex[,] a, int n, complex[] b, out int info, out densesolverreport rep, out complex[] x) { info = 0; rep = new densesolverreport(); x = new complex[0]; densesolver._pexec_cmatrixsolve(a, n, b, ref info, rep.innerobj, ref x); return; }
/************************************************************************* Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. *************************************************************************/ public static void _pexec_hpdmatrixsolve(complex[,] a, int n, bool isupper, complex[] b, ref int info, densesolverreport rep, ref complex[] x) { hpdmatrixsolve(a,n,isupper,b,ref info,rep,ref x); }
/************************************************************************* Dense solver. Same as RMatrixLUSolve(), but for HPD matrices represented by their Cholesky decomposition. 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. 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 Info - same as in RMatrixSolve Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void hpdmatrixcholeskysolve(complex[,] cha, int n, bool isupper, complex[] b, ref int info, densesolverreport rep, ref complex[] x) { complex[,] bm = new complex[0,0]; complex[,] xm = new complex[0,0]; int i_ = 0; info = 0; x = new complex[0]; if( n<=0 ) { info = -1; return; } bm = new complex[n, 1]; for(i_=0; i_<=n-1;i_++) { bm[i_,0] = b[i_]; } hpdmatrixcholeskysolvem(cha, n, isupper, bm, 1, ref info, rep, ref xm); x = new complex[n]; for(i_=0; i_<=n-1;i_++) { x[i_] = xm[i_,0]; } }
/************************************************************************* Dense solver. Same as RMatrixSolveM(), but for complex matrices. Algorithm features: * automatic detection of degenerate cases * condition number estimation * iterative refinement * O(N^3+M*N^2) complexity COMMERCIAL EDITION OF ALGLIB: ! Commercial version of ALGLIB includes two important improvements of ! this function, which can be used from C++ and C#: ! * Intel MKL support (lightweight Intel MKL is shipped with ALGLIB) ! * multicore support ! ! Intel MKL gives approximately constant (with respect to number of ! worker threads) acceleration factor which depends on CPU being used, ! problem size and "baseline" ALGLIB edition which is used for ! comparison. ! ! Say, on SSE2-capable CPU with N=1024, HPC ALGLIB will be: ! * about 2-3x faster than ALGLIB for C++ without MKL ! * about 7-10x faster than "pure C#" edition of ALGLIB ! Difference in performance will be more striking on newer CPU's with ! support for newer SIMD instructions. Generally, MKL accelerates any ! problem whose size is at least 128, with best efficiency achieved for ! N's larger than 512. ! ! Commercial edition of ALGLIB also supports multithreaded acceleration ! of this function. We should note that LU decomposition is harder to ! parallelize than, say, matrix-matrix product - this algorithm has ! many internal synchronization points which can not be avoided. However ! parallelism starts to be profitable starting from N=1024, achieving ! near-linear speedup for N=4096 or higher. ! ! In order to use multicore features you have to: ! * use commercial version of ALGLIB ! * call this function with "smp_" prefix, which indicates that ! multicore code will be used (for multicore support) ! ! 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 - 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 Info - same as in RMatrixSolve Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void cmatrixsolvem(complex[,] a, int n, complex[,] b, int m, bool rfs, ref int info, densesolverreport rep, ref complex[,] x) { complex[,] da = new complex[0,0]; complex[,] emptya = new complex[0,0]; int[] p = new int[0]; double scalea = 0; int i = 0; int j = 0; int i_ = 0; info = 0; x = new complex[0,0]; // // prepare: check inputs, allocate space... // if( n<=0 || m<=0 ) { info = -1; return; } da = new complex[n, n]; // // 1. scale matrix, max(|A[i,j]|) // 2. factorize scaled matrix // 3. solve // scalea = 0; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { scalea = Math.Max(scalea, math.abscomplex(a[i,j])); } } if( (double)(scalea)==(double)(0) ) { scalea = 1; } scalea = 1/scalea; for(i=0; i<=n-1; i++) { for(i_=0; i_<=n-1;i_++) { da[i,i_] = a[i,i_]; } } trfac.cmatrixlu(ref da, n, n, ref p); if( rfs ) { cmatrixlusolveinternal(da, p, scalea, n, a, true, b, m, ref info, rep, ref x); } else { cmatrixlusolveinternal(da, p, scalea, n, emptya, false, b, m, ref info, rep, ref x); } }
/************************************************************************* 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 NxM real matrices. 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. 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 Info - same as in RMatrixSolve Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void rmatrixlusolve(double[,] lua, int[] p, int n, double[] b, out int info, out densesolverreport rep, out double[] x) { info = 0; rep = new densesolverreport(); x = new double[0]; densesolver.rmatrixlusolve(lua, p, n, b, ref info, rep.innerobj, ref x); return; }
public static void smp_rmatrixsolvem(double[,] a, int n, double[,] b, int m, bool rfs, out int info, out densesolverreport rep, out double[,] x) { info = 0; rep = new densesolverreport(); x = new double[0,0]; densesolver._pexec_rmatrixsolvem(a, n, b, m, rfs, ref info, rep.innerobj, ref x); return; }
/************************************************************************* 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 Info - same as in RMatrixSolveM Rep - same as in RMatrixSolveM X - same as in RMatrixSolveM -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void rmatrixmixedsolve(double[,] a, double[,] lua, int[] p, int n, double[] b, ref int info, densesolverreport rep, ref double[] x) { double[,] bm = new double[0,0]; double[,] xm = new double[0,0]; int i_ = 0; info = 0; x = new double[0]; if( n<=0 ) { info = -1; return; } bm = new double[n, 1]; for(i_=0; i_<=n-1;i_++) { bm[i_,0] = b[i_]; } rmatrixmixedsolvem(a, lua, p, n, bm, 1, ref info, rep, ref xm); x = new double[n]; for(i_=0; i_<=n-1;i_++) { x[i_] = xm[i_,0]; } }
/************************************************************************* Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. *************************************************************************/ public static void _pexec_rmatrixsolvem(double[,] a, int n, double[,] b, int m, bool rfs, ref int info, densesolverreport rep, ref double[,] x) { rmatrixsolvem(a,n,b,m,rfs,ref info,rep,ref x); }
/************************************************************************* Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. *************************************************************************/ public static void _pexec_rmatrixsolve(double[,] a, int n, double[] b, ref int info, densesolverreport rep, ref double[] x) { rmatrixsolve(a,n,b,ref info,rep,ref x); }
public override alglib.apobject make_copy() { densesolverreport _result = new densesolverreport(); _result.r1 = r1; _result.rinf = rinf; return _result; }
/************************************************************************* Dense solver. Same as RMatrixSolveM(), but for Hermitian positive definite matrices. 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. COMMERCIAL EDITION OF ALGLIB: ! Commercial version of ALGLIB includes two important improvements of ! this function, which can be used from C++ and C#: ! * Intel MKL support (lightweight Intel MKL is shipped with ALGLIB) ! * multicore support ! ! Intel MKL gives approximately constant (with respect to number of ! worker threads) acceleration factor which depends on CPU being used, ! problem size and "baseline" ALGLIB edition which is used for ! comparison. ! ! Say, on SSE2-capable CPU with N=1024, HPC ALGLIB will be: ! * about 2-3x faster than ALGLIB for C++ without MKL ! * about 7-10x faster than "pure C#" edition of ALGLIB ! Difference in performance will be more striking on newer CPU's with ! support for newer SIMD instructions. Generally, MKL accelerates any ! problem whose size is at least 128, with best efficiency achieved for ! N's larger than 512. ! ! Commercial edition of ALGLIB also supports multithreaded acceleration ! of this function. We should note that Cholesky decomposition is harder ! to parallelize than, say, matrix-matrix product - this algorithm has ! several synchronization points which can not be avoided. However, ! parallelism starts to be profitable starting from N=500. ! ! In order to use multicore features you have to: ! * use commercial version of ALGLIB ! * call this function with "smp_" prefix, which indicates that ! multicore code will be used (for multicore support) ! ! 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 - 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 Info - same as in RMatrixSolve. Returns -3 for non-HPD matrices. Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void hpdmatrixsolvem(complex[,] a, int n, bool isupper, complex[,] b, int m, ref int info, densesolverreport rep, ref complex[,] x) { complex[,] da = new complex[0,0]; double sqrtscalea = 0; int i = 0; int j = 0; int j1 = 0; int j2 = 0; int i_ = 0; info = 0; x = new complex[0,0]; // // prepare: check inputs, allocate space... // if( n<=0 || m<=0 ) { info = -1; return; } da = new complex[n, n]; // // 1. scale matrix, max(|A[i,j]|) // 2. factorize scaled matrix // 3. solve // sqrtscalea = 0; for(i=0; i<=n-1; i++) { if( isupper ) { j1 = i; j2 = n-1; } else { j1 = 0; j2 = i; } for(j=j1; j<=j2; j++) { sqrtscalea = Math.Max(sqrtscalea, math.abscomplex(a[i,j])); } } if( (double)(sqrtscalea)==(double)(0) ) { sqrtscalea = 1; } sqrtscalea = 1/sqrtscalea; sqrtscalea = Math.Sqrt(sqrtscalea); for(i=0; i<=n-1; i++) { if( isupper ) { j1 = i; j2 = n-1; } else { j1 = 0; j2 = i; } for(i_=j1; i_<=j2;i_++) { da[i,i_] = a[i,i_]; } } if( !trfac.hpdmatrixcholesky(ref da, n, isupper) ) { x = new complex[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { x[i,j] = 0; } } rep.r1 = 0; rep.rinf = 0; info = -3; return; } info = 1; hpdmatrixcholeskysolveinternal(da, sqrtscalea, n, isupper, a, true, b, m, ref info, rep, ref x); }
/************************************************************************* Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. *************************************************************************/ public static void _pexec_cmatrixsolvem(complex[,] a, int n, complex[,] b, int m, bool rfs, ref int info, densesolverreport rep, ref complex[,] x) { cmatrixsolvem(a,n,b,m,rfs,ref info,rep,ref x); }
/************************************************************************* 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 Info - same as in RMatrixSolveM Rep - same as in RMatrixSolveM X - same as in RMatrixSolveM -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void rmatrixmixedsolvem(double[,] a, double[,] lua, int[] p, int n, double[,] b, int m, out int info, out densesolverreport rep, out double[,] x) { info = 0; rep = new densesolverreport(); x = new double[0,0]; densesolver.rmatrixmixedsolvem(a, lua, p, n, b, m, ref info, rep.innerobj, ref x); return; }
/************************************************************************* Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. *************************************************************************/ public static void _pexec_cmatrixsolve(complex[,] a, int n, complex[] b, ref int info, densesolverreport rep, ref complex[] x) { cmatrixsolve(a,n,b,ref info,rep,ref x); }
/************************************************************************* Dense solver. Same as RMatrixLUSolveM(), but for HPD matrices represented by their Cholesky decomposition. 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. INPUT PARAMETERS CHA - array[0..N-1,0..N-1], Cholesky decomposition, HPDMatrixCholesky 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 Info - same as in RMatrixSolve Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void hpdmatrixcholeskysolvem(complex[,] cha, int n, bool isupper, complex[,] b, int m, ref int info, densesolverreport rep, ref complex[,] x) { complex[,] emptya = new complex[0,0]; double sqrtscalea = 0; int i = 0; int j = 0; int j1 = 0; int j2 = 0; info = 0; x = new complex[0,0]; // // prepare: check inputs, allocate space... // if( n<=0 || m<=0 ) { info = -1; return; } // // 1. scale matrix, max(|U[i,j]|) // 2. factorize scaled matrix // 3. solve // sqrtscalea = 0; for(i=0; i<=n-1; i++) { if( isupper ) { j1 = i; j2 = n-1; } else { j1 = 0; j2 = i; } for(j=j1; j<=j2; j++) { sqrtscalea = Math.Max(sqrtscalea, math.abscomplex(cha[i,j])); } } if( (double)(sqrtscalea)==(double)(0) ) { sqrtscalea = 1; } sqrtscalea = 1/sqrtscalea; hpdmatrixcholeskysolveinternal(cha, sqrtscalea, n, isupper, emptya, false, b, m, ref info, rep, ref x); }
/************************************************************************* Dense solver. Same as RMatrixLUSolveM(), but for complex matrices. 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. 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 Info - same as in RMatrixSolve Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void cmatrixlusolvem(complex[,] lua, int[] p, int n, complex[,] b, int m, ref int info, densesolverreport rep, ref complex[,] x) { complex[,] emptya = new complex[0,0]; int i = 0; int j = 0; double scalea = 0; info = 0; x = new complex[0,0]; // // prepare: check inputs, allocate space... // if( n<=0 || m<=0 ) { info = -1; return; } // // 1. scale matrix, max(|U[i,j]|) // we assume that LU is in its normal form, i.e. |L[i,j]|<=1 // 2. solve // scalea = 0; for(i=0; i<=n-1; i++) { for(j=i; j<=n-1; j++) { scalea = Math.Max(scalea, math.abscomplex(lua[i,j])); } } if( (double)(scalea)==(double)(0) ) { scalea = 1; } scalea = 1/scalea; cmatrixlusolveinternal(lua, p, scalea, n, emptya, false, b, m, ref info, rep, ref x); }
/************************************************************************* Dense solver. Same as RMatrixSolveM(), but for complex matrices. Algorithm features: * automatic detection of degenerate cases * condition number estimation * iterative refinement * O(N^3+M*N^2) complexity COMMERCIAL EDITION OF ALGLIB: ! Commercial version of ALGLIB includes two important improvements of ! this function, which can be used from C++ and C#: ! * Intel MKL support (lightweight Intel MKL is shipped with ALGLIB) ! * multicore support ! ! Intel MKL gives approximately constant (with respect to number of ! worker threads) acceleration factor which depends on CPU being used, ! problem size and "baseline" ALGLIB edition which is used for ! comparison. ! ! Say, on SSE2-capable CPU with N=1024, HPC ALGLIB will be: ! * about 2-3x faster than ALGLIB for C++ without MKL ! * about 7-10x faster than "pure C#" edition of ALGLIB ! Difference in performance will be more striking on newer CPU's with ! support for newer SIMD instructions. Generally, MKL accelerates any ! problem whose size is at least 128, with best efficiency achieved for ! N's larger than 512. ! ! Commercial edition of ALGLIB also supports multithreaded acceleration ! of this function. We should note that LU decomposition is harder to ! parallelize than, say, matrix-matrix product - this algorithm has ! many internal synchronization points which can not be avoided. However ! parallelism starts to be profitable starting from N=1024, achieving ! near-linear speedup for N=4096 or higher. ! ! In order to use multicore features you have to: ! * use commercial version of ALGLIB ! * call this function with "smp_" prefix, which indicates that ! multicore code will be used (for multicore support) ! ! 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 - 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 Info - same as in RMatrixSolve Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void cmatrixsolvem(complex[,] a, int n, complex[,] b, int m, bool rfs, out int info, out densesolverreport rep, out complex[,] x) { info = 0; rep = new densesolverreport(); x = new complex[0,0]; densesolver.cmatrixsolvem(a, n, b, m, rfs, ref info, rep.innerobj, ref x); return; }
/************************************************************************* 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 Info - same as in RMatrixSolveM Rep - same as in RMatrixSolveM X - same as in RMatrixSolveM -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void cmatrixmixedsolvem(complex[,] a, complex[,] lua, int[] p, int n, complex[,] b, int m, ref int info, densesolverreport rep, ref complex[,] x) { double scalea = 0; int i = 0; int j = 0; info = 0; x = new complex[0,0]; // // prepare: check inputs, allocate space... // if( n<=0 || m<=0 ) { info = -1; return; } // // 1. scale matrix, max(|A[i,j]|) // 2. factorize scaled matrix // 3. solve // scalea = 0; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { scalea = Math.Max(scalea, math.abscomplex(a[i,j])); } } if( (double)(scalea)==(double)(0) ) { scalea = 1; } scalea = 1/scalea; cmatrixlusolveinternal(lua, p, scalea, n, a, true, b, m, ref info, rep, ref x); }
/************************************************************************* Internal Cholesky solver -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ private static void hpdmatrixcholeskysolveinternal(complex[,] cha, double sqrtscalea, int n, bool isupper, complex[,] a, bool havea, complex[,] b, int m, ref int info, densesolverreport rep, ref complex[,] x) { int i = 0; int j = 0; int k = 0; complex[] xc = new complex[0]; complex[] y = new complex[0]; complex[] bc = new complex[0]; complex[] xa = new complex[0]; complex[] xb = new complex[0]; complex[] tx = new complex[0]; double v = 0; double mxb = 0; double scaleright = 0; int i_ = 0; info = 0; x = new complex[0,0]; alglib.ap.assert((double)(sqrtscalea)>(double)(0)); // // prepare: check inputs, allocate space... // if( n<=0 || m<=0 ) { info = -1; return; } x = new complex[n, m]; y = new complex[n]; xc = new complex[n]; bc = new complex[n]; tx = new complex[n+1]; xa = new complex[n+1]; xb = new complex[n+1]; // // estimate condition number, test for near singularity // rep.r1 = rcond.hpdmatrixcholeskyrcond(cha, n, isupper); rep.rinf = rep.r1; if( (double)(rep.r1)<(double)(rcond.rcondthreshold()) ) { for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { x[i,j] = 0; } } rep.r1 = 0; rep.rinf = 0; info = -3; return; } info = 1; // // solve // for(k=0; k<=m-1; k++) { // // copy B to contiguous storage // for(i_=0; i_<=n-1;i_++) { bc[i_] = b[i_,k]; } // // Scale right part: // * MX stores max(|Bi|) // * ScaleRight stores actual scaling applied to B when solving systems // it is chosen to make |scaleRight*b| close to 1. // mxb = 0; for(i=0; i<=n-1; i++) { mxb = Math.Max(mxb, math.abscomplex(bc[i])); } if( (double)(mxb)==(double)(0) ) { mxb = 1; } scaleright = 1/mxb; // // First, non-iterative part of solution process. // We use separate code for this task because // XDot is quite slow and we want to save time. // for(i_=0; i_<=n-1;i_++) { xc[i_] = scaleright*bc[i_]; } hpdbasiccholeskysolve(cha, sqrtscalea, n, isupper, ref xc, ref tx); // // Store xc. // Post-scale result. // v = math.sqr(sqrtscalea)*mxb; for(i_=0; i_<=n-1;i_++) { x[i_,k] = v*xc[i_]; } } }
/************************************************************************* 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 Info - same as in RMatrixSolveM Rep - same as in RMatrixSolveM X - same as in RMatrixSolveM -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void cmatrixmixedsolve(complex[,] a, complex[,] lua, int[] p, int n, complex[] b, ref int info, densesolverreport rep, ref complex[] x) { complex[,] bm = new complex[0,0]; complex[,] xm = new complex[0,0]; int i_ = 0; info = 0; x = new complex[0]; if( n<=0 ) { info = -1; return; } bm = new complex[n, 1]; for(i_=0; i_<=n-1;i_++) { bm[i_,0] = b[i_]; } cmatrixmixedsolvem(a, lua, p, n, bm, 1, ref info, rep, ref xm); x = new complex[n]; for(i_=0; i_<=n-1;i_++) { x[i_] = xm[i_,0]; } }
/************************************************************************* Dense solver. Same as RMatrixLUSolveM(), but for complex matrices. 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. 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 Info - same as in RMatrixSolve Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void cmatrixlusolvem(complex[,] lua, int[] p, int n, complex[,] b, int m, out int info, out densesolverreport rep, out complex[,] x) { info = 0; rep = new densesolverreport(); x = new complex[0,0]; densesolver.cmatrixlusolvem(lua, p, n, b, m, ref info, rep.innerobj, ref x); return; }
/************************************************************************* Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. *************************************************************************/ public static void _pexec_spdmatrixsolve(double[,] a, int n, bool isupper, double[] b, ref int info, densesolverreport rep, ref double[] x) { spdmatrixsolve(a,n,isupper,b,ref info,rep,ref x); }
/************************************************************************* Dense solver. Same as RMatrixSolveM(), but for symmetric positive definite matrices. 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. COMMERCIAL EDITION OF ALGLIB: ! Commercial version of ALGLIB includes two important improvements of ! this function, which can be used from C++ and C#: ! * Intel MKL support (lightweight Intel MKL is shipped with ALGLIB) ! * multicore support ! ! Intel MKL gives approximately constant (with respect to number of ! worker threads) acceleration factor which depends on CPU being used, ! problem size and "baseline" ALGLIB edition which is used for ! comparison. ! ! Say, on SSE2-capable CPU with N=1024, HPC ALGLIB will be: ! * about 2-3x faster than ALGLIB for C++ without MKL ! * about 7-10x faster than "pure C#" edition of ALGLIB ! Difference in performance will be more striking on newer CPU's with ! support for newer SIMD instructions. Generally, MKL accelerates any ! problem whose size is at least 128, with best efficiency achieved for ! N's larger than 512. ! ! Commercial edition of ALGLIB also supports multithreaded acceleration ! of this function. We should note that Cholesky decomposition is harder ! to parallelize than, say, matrix-matrix product - this algorithm has ! several synchronization points which can not be avoided. However, ! parallelism starts to be profitable starting from N=500. ! ! In order to use multicore features you have to: ! * use commercial version of ALGLIB ! * call this function with "smp_" prefix, which indicates that ! multicore code will be used (for multicore support) ! ! 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 - 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 Info - same as in RMatrixSolve. Returns -3 for non-SPD matrices. Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void spdmatrixsolvem(double[,] a, int n, bool isupper, double[,] b, int m, out int info, out densesolverreport rep, out double[,] x) { info = 0; rep = new densesolverreport(); x = new double[0,0]; densesolver.spdmatrixsolvem(a, n, isupper, b, m, ref info, rep.innerobj, ref x); return; }
/************************************************************************* Dense solver. Same as RMatrixLUSolve(), but for SPD matrices represented by their Cholesky decomposition. 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. 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 Info - same as in RMatrixSolve Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void spdmatrixcholeskysolve(double[,] cha, int n, bool isupper, double[] b, ref int info, densesolverreport rep, ref double[] x) { double[,] bm = new double[0,0]; double[,] xm = new double[0,0]; int i_ = 0; info = 0; x = new double[0]; if( n<=0 ) { info = -1; return; } bm = new double[n, 1]; for(i_=0; i_<=n-1;i_++) { bm[i_,0] = b[i_]; } spdmatrixcholeskysolvem(cha, n, isupper, bm, 1, ref info, rep, ref xm); x = new double[n]; for(i_=0; i_<=n-1;i_++) { x[i_] = xm[i_,0]; } }
/************************************************************************* Dense solver. Same as RMatrixLUSolve(), but for SPD matrices represented by their Cholesky decomposition. 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. 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 Info - same as in RMatrixSolve Rep - same as in RMatrixSolve X - same as in RMatrixSolve -- ALGLIB -- Copyright 27.01.2010 by Bochkanov Sergey *************************************************************************/ public static void spdmatrixcholeskysolve(double[,] cha, int n, bool isupper, double[] b, out int info, out densesolverreport rep, out double[] x) { info = 0; rep = new densesolverreport(); x = new double[0]; densesolver.spdmatrixcholeskysolve(cha, n, isupper, b, ref info, rep.innerobj, ref x); return; }
public static void smp_hpdmatrixsolvem(complex[,] a, int n, bool isupper, complex[,] b, int m, out int info, out densesolverreport rep, out complex[,] x) { info = 0; rep = new densesolverreport(); x = new complex[0,0]; densesolver._pexec_hpdmatrixsolvem(a, n, isupper, b, m, ref info, rep.innerobj, ref x); return; }