// On input, LU and ipiv is LU factorization of A. On output, LU is overwritten. // Works for any m, n. // Uses init_matrix() to re-generate original A as needed. // Returns error in factorization, |PA - LU| / (n |A|) // This allocates 3 more matrices to store A, L, and U. double get_LU_error(magma_int_t M, magma_int_t N, double *LU, magma_int_t lda, magma_int_t *ipiv) { magma_int_t min_mn = min(M,N); magma_int_t ione = 1; magma_int_t i, j; double alpha = MAGMA_D_ONE; double beta = MAGMA_D_ZERO; double *A, *L, *U; double work[1], matnorm, residual; TESTING_MALLOC_CPU( A, double, lda*N ); TESTING_MALLOC_CPU( L, double, M*min_mn ); TESTING_MALLOC_CPU( U, double, min_mn*N ); memset( L, 0, M*min_mn*sizeof(double) ); memset( U, 0, min_mn*N*sizeof(double) ); // set to original A init_matrix( M, N, A, lda ); lapackf77_dlaswp( &N, A, &lda, &ione, &min_mn, ipiv, &ione); // copy LU to L and U, and set diagonal to 1 lapackf77_dlacpy( MagmaLowerStr, &M, &min_mn, LU, &lda, L, &M ); lapackf77_dlacpy( MagmaUpperStr, &min_mn, &N, LU, &lda, U, &min_mn ); for(j=0; j<min_mn; j++) L[j+j*M] = MAGMA_D_MAKE( 1., 0. ); matnorm = lapackf77_dlange("f", &M, &N, A, &lda, work); blasf77_dgemm("N", "N", &M, &N, &min_mn, &alpha, L, &M, U, &min_mn, &beta, LU, &lda); for( j = 0; j < N; j++ ) { for( i = 0; i < M; i++ ) { LU[i+j*lda] = MAGMA_D_SUB( LU[i+j*lda], A[i+j*lda] ); } } residual = lapackf77_dlange("f", &M, &N, LU, &lda, work); TESTING_FREE_CPU( A ); TESTING_FREE_CPU( L ); TESTING_FREE_CPU( U ); return residual / (matnorm * N); }
double get_LU_error(magma_int_t M, magma_int_t N, double *A, magma_int_t lda, double *LU, magma_int_t *IPIV) { magma_int_t min_mn = min(M,N); magma_int_t ione = 1; magma_int_t i, j; double alpha = MAGMA_D_ONE; double beta = MAGMA_D_ZERO; double *L, *U; double work[1], matnorm, residual; TESTING_MALLOC( L, double, M*min_mn); TESTING_MALLOC( U, double, min_mn*N); memset( L, 0, M*min_mn*sizeof(double) ); memset( U, 0, min_mn*N*sizeof(double) ); lapackf77_dlaswp( &N, A, &lda, &ione, &min_mn, IPIV, &ione); lapackf77_dlacpy( MagmaLowerStr, &M, &min_mn, LU, &lda, L, &M ); lapackf77_dlacpy( MagmaUpperStr, &min_mn, &N, LU, &lda, U, &min_mn ); for(j=0; j<min_mn; j++) L[j+j*M] = MAGMA_D_MAKE( 1., 0. ); matnorm = lapackf77_dlange("f", &M, &N, A, &lda, work); blasf77_dgemm("N", "N", &M, &N, &min_mn, &alpha, L, &M, U, &min_mn, &beta, LU, &lda); for( j = 0; j < N; j++ ) { for( i = 0; i < M; i++ ) { LU[i+j*lda] = MAGMA_D_SUB( LU[i+j*lda], A[i+j*lda] ); } } residual = lapackf77_dlange("f", &M, &N, LU, &lda, work); TESTING_FREE(L); TESTING_FREE(U); return residual / (matnorm * N); }