/************************************************************************* Calculation of the determinant of a general matrix Input parameters: A - matrix, array[0..N-1, 0..N-1] N - size of matrix A. Result: determinant of matrix A. -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/ public static AP.Complex cmatrixdet(AP.Complex[,] a, int n) { AP.Complex result = 0; int[] pivots = new int[0]; a = (AP.Complex[,])a.Clone(); trfac.cmatrixlu(ref a, n, n, ref pivots); result = cmatrixludet(ref a, ref pivots, n); return result; }
private void InitializeActionPresenter(ActionPresenter ap) { var apChangingImg = ap as IActionPresenterChangingResultImage; if (apChangingImg != null) { if (!m_isHereActionChangingResultImage) { m_isHereActionChangingResultImage = true; apChangingImg.NewResultImageIsReady += (sender, e) => { var apChanginImage = sender as IActionPresenterChangingResultImage; m_commonViewModel.ResultImageSource = apChanginImage.NewResultImage; ImageSource img = apChanginImage.NewResultImage.Clone(); img.Freeze(); this.LastResultImage = img; }; } else { return; } } var apNeedingProperty = ap as IActionPresenterNeedingCameraProperty <float>; if (apNeedingProperty != null) { apNeedingProperty.SetNeededCameraProperty += (sender, e) => { var sendr = sender as IActionPresenterNeedingCameraProperty <float>; sendr.CurrentNeededPropertyValue = m_camera.GetProperty(sendr.NeededPropertyType).absValue; }; } ap.IsNeedImageChanged += (sender, e) => { var apChangingImage = sender as IActionPresenterChangingResultImage; if (apChangingImage != null) { m_isHereActionChangingResultImage = false; } var AP = sender as ActionPresenter; m_actions.TryRemove(AP.ID, out AP); }; m_actions.AddOrUpdate(ap.ID, ap, (str, AP) => AP.Clone() as ActionPresenter); }
/************************************************************************* 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. 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 *************************************************************************/ public static bool hmatrixevd(AP.Complex[,] a, int n, int zneeded, bool isupper, ref double[] d, ref AP.Complex[,] z) { bool result = new bool(); AP.Complex[] tau = new AP.Complex[0]; double[] e = new double[0]; double[] work = new double[0]; double[,] t = new double[0, 0]; AP.Complex[,] q = new AP.Complex[0, 0]; int i = 0; int k = 0; double v = 0; int i_ = 0; a = (AP.Complex[,])a.Clone(); System.Diagnostics.Debug.Assert(zneeded == 0 | zneeded == 1, "HermitianEVD: incorrect ZNeeded"); // // Reduce to tridiagonal form // ortfac.hmatrixtd(ref a, n, isupper, ref tau, ref d, ref e); if (zneeded == 1) { ortfac.hmatrixtdunpackq(ref a, n, isupper, ref tau, ref q); zneeded = 2; } // // TDEVD // result = smatrixtdevd(ref d, e, n, zneeded, ref t); // // Eigenvectors are needed // Calculate Z = Q*T = Re(Q)*T + i*Im(Q)*T // if (result & zneeded != 0) { work = new double[n - 1 + 1]; z = new AP.Complex[n - 1 + 1, n - 1 + 1]; for (i = 0; i <= n - 1; i++) { // // Calculate real part // for (k = 0; k <= n - 1; k++) { work[k] = 0; } for (k = 0; k <= n - 1; k++) { v = q[i, k].x; for (i_ = 0; i_ <= n - 1; i_++) { work[i_] = work[i_] + v * t[k, i_]; } } for (k = 0; k <= n - 1; k++) { z[i, k].x = work[k]; } // // Calculate imaginary part // for (k = 0; k <= n - 1; k++) { work[k] = 0; } for (k = 0; k <= n - 1; k++) { v = q[i, k].y; for (i_ = 0; i_ <= n - 1; i_++) { work[i_] = work[i_] + v * t[k, i_]; } } for (k = 0; k <= n - 1; k++) { z[i, k].y = work[k]; } } } return result; }
/************************************************************************* Estimate of a matrix condition number (infinity-norm). The algorithm calculates a lower bound of the condition number. In this case, the algorithm does not return a lower bound of the condition number, but an inverse number (to avoid an overflow in case of a singular matrix). Input parameters: A - matrix. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. Result: 1/LowerBound(cond(A)) NOTE: if k(A) is very large, then matrix is assumed degenerate, k(A)=INF, 0.0 is returned in such cases. *************************************************************************/ public static double cmatrixrcondinf(AP.Complex[,] a, int n) { double result = 0; int i = 0; int j = 0; double v = 0; double nrm = 0; int[] pivots = new int[0]; a = (AP.Complex[,])a.Clone(); System.Diagnostics.Debug.Assert(n >= 1, "CMatrixRCondInf: N<1!"); nrm = 0; for (i = 0; i <= n - 1; i++) { v = 0; for (j = 0; j <= n - 1; j++) { v = v + AP.Math.AbsComplex(a[i, j]); } nrm = Math.Max(nrm, v); } trfac.cmatrixlu(ref a, n, n, ref pivots); cmatrixrcondluinternal(ref a, n, false, true, nrm, ref v); result = v; return result; }
/************************************************************************* Estimate of a matrix condition number (1-norm) The algorithm calculates a lower bound of the condition number. In this case, the algorithm does not return a lower bound of the condition number, but an inverse number (to avoid an overflow in case of a singular matrix). Input parameters: A - matrix. Array whose indexes range within [0..N-1, 0..N-1]. N - size of matrix A. Result: 1/LowerBound(cond(A)) NOTE: if k(A) is very large, then matrix is assumed degenerate, k(A)=INF, 0.0 is returned in such cases. *************************************************************************/ public static double cmatrixrcond1(AP.Complex[,] a, int n) { double result = 0; int i = 0; int j = 0; double v = 0; double nrm = 0; int[] pivots = new int[0]; double[] t = new double[0]; a = (AP.Complex[,])a.Clone(); System.Diagnostics.Debug.Assert(n >= 1, "CMatrixRCond1: N<1!"); t = new double[n]; for (i = 0; i <= n - 1; i++) { t[i] = 0; } for (i = 0; i <= n - 1; i++) { for (j = 0; j <= n - 1; j++) { t[j] = t[j] + AP.Math.AbsComplex(a[i, j]); } } nrm = 0; for (i = 0; i <= n - 1; i++) { nrm = Math.Max(nrm, t[i]); } trfac.cmatrixlu(ref a, n, n, ref pivots); cmatrixrcondluinternal(ref a, n, true, true, nrm, ref v); result = v; return result; }
/************************************************************************* Condition number estimate of a Hermitian positive definite matrix. The algorithm calculates a lower bound of the condition number. In this case, the algorithm does not return a lower bound of the condition number, but an inverse number (to avoid an overflow in case of a singular matrix). It should be noted that 1-norm and inf-norm of condition numbers of symmetric matrices are equal, so the algorithm doesn't take into account the differences between these types of norms. Input parameters: A - Hermitian positive definite matrix which is given by its upper or lower triangle depending on the value of IsUpper. Array with elements [0..N-1, 0..N-1]. N - size of matrix A. IsUpper - storage format. Result: 1/LowerBound(cond(A)), if matrix A is positive definite, -1, if matrix A is not positive definite, and its condition number could not be found by this algorithm. NOTE: if k(A) is very large, then matrix is assumed degenerate, k(A)=INF, 0.0 is returned in such cases. *************************************************************************/ public static double hpdmatrixrcond(AP.Complex[,] a, int n, bool isupper) { double result = 0; int i = 0; int j = 0; int j1 = 0; int j2 = 0; double v = 0; double nrm = 0; double[] t = new double[0]; a = (AP.Complex[,])a.Clone(); t = new double[n]; for (i = 0; i <= n - 1; i++) { t[i] = 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++) { if (i == j) { t[i] = t[i] + AP.Math.AbsComplex(a[i, i]); } else { t[i] = t[i] + AP.Math.AbsComplex(a[i, j]); t[j] = t[j] + AP.Math.AbsComplex(a[i, j]); } } } nrm = 0; for (i = 0; i <= n - 1; i++) { nrm = Math.Max(nrm, t[i]); } if (trfac.hpdmatrixcholesky(ref a, n, isupper)) { hpdmatrixrcondcholeskyinternal(ref a, n, isupper, true, nrm, ref v); result = v; } else { result = -1; } return result; }
/************************************************************************* Tests whether A is HPD *************************************************************************/ private static bool ishpd(AP.Complex[,] a, int n) { bool result = new bool(); int j = 0; double ajj = 0; AP.Complex v = 0; double r = 0; AP.Complex[] t = new AP.Complex[0]; AP.Complex[] t2 = new AP.Complex[0]; AP.Complex[] t3 = new AP.Complex[0]; int i = 0; AP.Complex[,] a1 = new AP.Complex[0,0]; int i_ = 0; a = (AP.Complex[,])a.Clone(); t = new AP.Complex[n-1+1]; t2 = new AP.Complex[n-1+1]; t3 = new AP.Complex[n-1+1]; result = true; // // Compute the Cholesky factorization A = U'*U. // for(j=0; j<=n-1; j++) { // // Compute U(J,J) and test for non-positive-definiteness. // v = 0.0; for(i_=0; i_<=j-1;i_++) { v += AP.Math.Conj(a[i_,j])*a[i_,j]; } ajj = (a[j,j]-v).x; if( (double)(ajj)<=(double)(0) ) { a[j,j] = ajj; result = false; return result; } ajj = Math.Sqrt(ajj); a[j,j] = ajj; // // Compute elements J+1:N-1 of row J. // if( j<n-1 ) { for(i_=0; i_<=j-1;i_++) { t2[i_] = AP.Math.Conj(a[i_,j]); } for(i_=j+1; i_<=n-1;i_++) { t3[i_] = a[j,i_]; } for(i=j+1; i<=n-1; i++) { v = 0.0; for(i_=0; i_<=j-1;i_++) { v += a[i_,i]*t2[i_]; } t3[i] = t3[i]-v; } for(i_=j+1; i_<=n-1;i_++) { a[j,i_] = t3[i_]; } r = 1/ajj; for(i_=j+1; i_<=n-1;i_++) { a[j,i_] = r*a[j,i_]; } } } return result; }
/************************************************************************* Checks whether inverse is correct Returns True on success. *************************************************************************/ private static bool hpdmatrixcheckinverse(AP.Complex[,] a, AP.Complex[,] inva, bool isupper, int n, double threshold, int info, ref matinv.matinvreport rep) { bool result = new bool(); int i = 0; int j = 0; AP.Complex v = 0; int i_ = 0; a = (AP.Complex[,])a.Clone(); inva = (AP.Complex[,])inva.Clone(); for(i=0; i<=n-2; i++) { if( isupper ) { for(i_=i+1; i_<=n-1;i_++) { a[i_,i] = AP.Math.Conj(a[i,i_]); } for(i_=i+1; i_<=n-1;i_++) { inva[i_,i] = AP.Math.Conj(inva[i,i_]); } } else { for(i_=i+1; i_<=n-1;i_++) { a[i,i_] = AP.Math.Conj(a[i_,i]); } for(i_=i+1; i_<=n-1;i_++) { inva[i,i_] = AP.Math.Conj(inva[i_,i]); } } } result = true; if( info<=0 ) { result = false; } else { result = result & !((double)(rep.r1)<(double)(100*AP.Math.MachineEpsilon) | (double)(rep.r1)>(double)(1+1000*AP.Math.MachineEpsilon)); result = result & !((double)(rep.rinf)<(double)(100*AP.Math.MachineEpsilon) | (double)(rep.rinf)>(double)(1+1000*AP.Math.MachineEpsilon)); for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { v = 0.0; for(i_=0; i_<=n-1;i_++) { v += a[i,i_]*inva[i_,j]; } if( i==j ) { v = v-1; } result = result & (double)(AP.Math.AbsComplex(v))<=(double)(threshold); } } } return result; }