bool inverse(ap::real_2d_array& a, int n) { bool result; ap::integer_1d_array pivots; ludecomposition(a, n, n, pivots); result = inverselu(a, pivots, n); return result; }
/************************************************************************* Obsolete 1-based subroutine. See RMatrixDet for 0-based replacement. *************************************************************************/ double determinant(ap::real_2d_array a, int n) { double result; ap::integer_1d_array pivots; ludecomposition(a, n, n, pivots); result = determinantlu(a, pivots, n); return result; }
/************************************************************************* LU-разложение матрицы общего вида размера M x N Использует LUDecomposition. По функциональности отличается тем, что выводит матрицы L и U не в компактной форме, а в виде отдельных матриц общего вида, заполненных в соответствующих местах нулевыми элементами. Подпрограмма приведена исключительно для демонстрации того, как "распаковывается" результат работы подпрограммы LUDecomposition -- ALGLIB -- Copyright 2005 by Bochkanov Sergey *************************************************************************/ void ludecompositionunpacked(ap::real_2d_array a, int m, int n, ap::real_2d_array& l, ap::real_2d_array& u, ap::integer_1d_array& pivots) { int i; int j; int minmn; if( m==0||n==0 ) { return; } minmn = ap::minint(m, n); l.setbounds(1, m, 1, minmn); u.setbounds(1, minmn, 1, n); ludecomposition(a, m, n, pivots); for(i = 1; i <= m; i++) { for(j = 1; j <= minmn; j++) { if( j>i ) { l(i,j) = 0; } if( j==i ) { l(i,j) = 1; } if( j<i ) { l(i,j) = a(i,j); } } } for(i = 1; i <= minmn; i++) { for(j = 1; j <= n; j++) { if( j<i ) { u(i,j) = 0; } if( j>=i ) { u(i,j) = a(i,j); } } } }
/************************************************************************* Obsolete 1-based subroutine *************************************************************************/ bool solvesystem(ap::real_2d_array a, ap::real_1d_array b, int n, ap::real_1d_array& x) { bool result; ap::integer_1d_array pivots; int i; ludecomposition(a, n, n, pivots); result = solvesystemlu(a, pivots, b, n, x); return result; }
//************************************************************************ void inv_LU(int Size, TFloat *inMatrix, TFloat *outMatrix) { // ------- Инициализация ----- масива ----- ap::real_2d_array ar; ar.setbounds(1,Size,1,Size); for(int i=0; i<Size; i++) { for(int j=0; j<Size; j++) { ar(i+1,j+1) = inMatrix[i*Size + j]; } } // ----------- ap::integer_1d_array pivots; ludecomposition(ar, Size, Size, pivots); bool result = inverselu(ar, pivots, Size); for( int i = 0; i < Size; i++) { for( int j = 0; j < Size; j++) { //outMatrix[j*Size+i] = outMatrix[i*Size + j] = ar(i+1,j+1); outMatrix[j*Size+i] = ar(i+1,j+1); } } }
/************************* * determine inverse of a * * binary matrix * *************************/ void inversematrix(int *matrix, int *inversematrix, int dimension) { int row, col, k; int *rhs, *roworder; /* allocate memory */ rhs = (int *)allocate(dimension * sizeof(int)); roworder = (int *)allocate(dimension * sizeof(int)); /* determine lu decomposition of matrix */ for (row = 0; row < dimension; row++) roworder[row] = row; ludecomposition(matrix, roworder, dimension); for (col = 0; col < dimension; col++) { /* clear field */ for (k = 0; k < dimension; k++) rhs[k] = 0; rhs[col] = 1; lusolve(matrix, rhs, roworder, dimension); for (k = 0; k < dimension; k++) { *(inversematrix + k * dimension + col) = rhs[k]; } } /* free space */ free(rhs); free(roworder); }
static void testluproblem(const ap::real_2d_array& a, int m, int n, double& diffpu, double& luerr) { ap::real_2d_array t1; ap::real_2d_array t2; ap::real_2d_array t3; ap::integer_1d_array it1; ap::integer_1d_array it2; int i; int j; int k; double v; double mx; ap::real_2d_array a0; ap::integer_1d_array p0; mx = 0; for(i = 1; i <= m; i++) { for(j = 1; j <= n; j++) { if( ap::fp_greater(fabs(a(i,j)),mx) ) { mx = fabs(a(i,j)); } } } if( ap::fp_eq(mx,0) ) { mx = 1; } // // Compare LU and unpacked LU // t1.setbounds(1, m, 1, n); for(i = 1; i <= m; i++) { ap::vmove(&t1(i, 1), &a(i, 1), ap::vlen(1,n)); } ludecomposition(t1, m, n, it1); ludecompositionunpacked(a, m, n, t2, t3, it2); for(i = 1; i <= m; i++) { for(j = 1; j <= ap::minint(m, n); j++) { if( i>j ) { diffpu = ap::maxreal(diffpu, fabs(t1(i,j)-t2(i,j))/mx); } if( i==j ) { diffpu = ap::maxreal(diffpu, fabs(1-t2(i,j))/mx); } if( i<j ) { diffpu = ap::maxreal(diffpu, fabs(0-t2(i,j))/mx); } } } for(i = 1; i <= ap::minint(m, n); i++) { for(j = 1; j <= n; j++) { if( i>j ) { diffpu = ap::maxreal(diffpu, fabs(0-t3(i,j))/mx); } if( i<=j ) { diffpu = ap::maxreal(diffpu, fabs(t1(i,j)-t3(i,j))/mx); } } } for(i = 1; i <= ap::minint(m, n); i++) { diffpu = ap::maxreal(diffpu, fabs(double(it1(i)-it2(i)))); } // // Test unpacked LU // ludecompositionunpacked(a, m, n, t1, t2, it1); t3.setbounds(1, m, 1, n); k = ap::minint(m, n); for(i = 1; i <= m; i++) { for(j = 1; j <= n; j++) { v = ap::vdotproduct(t1.getrow(i, 1, k), t2.getcolumn(j, 1, k)); t3(i,j) = v; } } for(i = ap::minint(m, n); i >= 1; i--) { if( i!=it1(i) ) { for(j = 1; j <= n; j++) { v = t3(i,j); t3(i,j) = t3(it1(i),j); t3(it1(i),j) = v; } } } for(i = 1; i <= m; i++) { for(j = 1; j <= n; j++) { luerr = ap::maxreal(luerr, fabs(a(i,j)-t3(i,j))/mx); } } // // Test 0-based LU // t1.setbounds(1, m, 1, n); for(i = 1; i <= m; i++) { ap::vmove(&t1(i, 1), &a(i, 1), ap::vlen(1,n)); } ludecomposition(t1, m, n, it1); a0.setbounds(0, m-1, 0, n-1); for(i = 0; i <= m-1; i++) { for(j = 0; j <= n-1; j++) { a0(i,j) = a(i+1,j+1); } } rmatrixlu(a0, m, n, p0); for(i = 0; i <= m-1; i++) { for(j = 0; j <= n-1; j++) { diffpu = ap::maxreal(diffpu, fabs(a0(i,j)-t1(i+1,j+1))); } } for(i = 0; i <= ap::minint(m-1, n-1); i++) { diffpu = ap::maxreal(diffpu, fabs(double(p0(i)+1-it1(i+1)))); } }