/* linalg/test.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2005 * Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include #include #include #include #include #include #include #include #include #define TEST_SVD_4X4 1 int check (double x, double actual, double eps); gsl_matrix * create_hilbert_matrix(unsigned long size); gsl_matrix * create_general_matrix(unsigned long size1, unsigned long size2); gsl_matrix * create_vandermonde_matrix(unsigned long size); gsl_matrix * create_moler_matrix(unsigned long size); gsl_matrix * create_row_matrix(unsigned long size1, unsigned long size2); gsl_matrix * create_2x2_matrix(double a11, double a12, double a21, double a22); gsl_matrix * create_diagonal_matrix(double a[], unsigned long size); int test_matmult(void); int test_matmult_mod(void); int test_LU_solve_dim(const gsl_matrix * m, const double * actual, double eps); int test_LU_solve(void); int test_LUc_solve_dim(const gsl_matrix_complex * m, const double * actual, double eps); int test_LUc_solve(void); int test_QR_solve_dim(const gsl_matrix * m, const double * actual, double eps); int test_QR_solve(void); int test_QR_QRsolve_dim(const gsl_matrix * m, const double * actual, double eps); int test_QR_QRsolve(void); int test_QR_lssolve_dim(const gsl_matrix * m, const double * actual, double eps); int test_QR_lssolve(void); int test_QR_decomp_dim(const gsl_matrix * m, double eps); int test_QR_decomp(void); int test_QRPT_solve_dim(const gsl_matrix * m, const double * actual, double eps); int test_QRPT_solve(void); int test_QRPT_QRsolve_dim(const gsl_matrix * m, const double * actual, double eps); int test_QRPT_QRsolve(void); int test_QRPT_decomp_dim(const gsl_matrix * m, double eps); int test_QRPT_decomp(void); int test_QR_update_dim(const gsl_matrix * m, double eps); int test_QR_update(void); int test_LQ_solve_dim(const gsl_matrix * m, const double * actual, double eps); int test_LQ_solve(void); int test_LQ_LQsolve_dim(const gsl_matrix * m, const double * actual, double eps); int test_LQ_LQsolve(void); int test_LQ_lssolve_dim(const gsl_matrix * m, const double * actual, double eps); int test_LQ_lssolve(void); int test_LQ_decomp_dim(const gsl_matrix * m, double eps); int test_LQ_decomp(void); int test_PTLQ_solve_dim(const gsl_matrix * m, const double * actual, double eps); int test_PTLQ_solve(void); int test_PTLQ_LQsolve_dim(const gsl_matrix * m, const double * actual, double eps); int test_PTLQ_LQsolve(void); int test_PTLQ_decomp_dim(const gsl_matrix * m, double eps); int test_PTLQ_decomp(void); int test_LQ_update_dim(const gsl_matrix * m, double eps); int test_LQ_update(void); int test_SV_solve_dim(const gsl_matrix * m, const double * actual, double eps); int test_SV_solve(void); int test_SV_decomp_dim(const gsl_matrix * m, double eps); int test_SV_decomp(void); int test_SV_decomp_mod_dim(const gsl_matrix * m, double eps); int test_SV_decomp_mod(void); int test_SV_decomp_jacobi_dim(const gsl_matrix * m, double eps); int test_SV_decomp_jacobi(void); int test_cholesky_solve_dim(const gsl_matrix * m, const double * actual, double eps); int test_cholesky_solve(void); int test_cholesky_decomp_dim(const gsl_matrix * m, double eps); int test_cholesky_decomp(void); int test_HH_solve_dim(const gsl_matrix * m, const double * actual, double eps); int test_HH_solve(void); int test_TDS_solve_dim(unsigned long dim, double d, double od, const double * actual, double eps); int test_TDS_solve(void); int test_TDN_solve_dim(unsigned long dim, double d, double a, double b, const double * actual, double eps); int test_TDN_solve(void); int test_TDS_cyc_solve_one(const unsigned long dim, const double * d, const double * od, const double * r, const double * actual, double eps); int test_TDS_cyc_solve(void); int test_TDN_cyc_solve_dim(unsigned long dim, double d, double a, double b, const double * actual, double eps); int test_TDN_cyc_solve(void); int test_bidiag_decomp_dim(const gsl_matrix * m, double eps); int test_bidiag_decomp(void); int check (double x, double actual, double eps) { if (x == actual) { return 0; } else if (actual == 0) { return fabs(x) > eps; } else { return (fabs(x - actual)/fabs(actual)) > eps; } } gsl_matrix * create_hilbert_matrix(unsigned long size) { unsigned long i, j; gsl_matrix * m = gsl_matrix_alloc(size, size); for(i=0; i GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 1) - 65.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 2) - 30.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 0) - 30.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 1) - 65.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 2) - 42.0) > GSL_DBL_EPSILON ); gsl_matrix_free(A); gsl_matrix_free(B); gsl_matrix_free(C); return s; } int test_matmult_mod(void) { int s = 0; gsl_matrix * A = gsl_matrix_calloc(3, 3); gsl_matrix * B = gsl_matrix_calloc(3, 3); gsl_matrix * C = gsl_matrix_calloc(3, 3); gsl_matrix * D = gsl_matrix_calloc(2, 3); gsl_matrix * E = gsl_matrix_calloc(2, 3); gsl_matrix * F = gsl_matrix_calloc(2, 2); gsl_matrix_set(A, 0, 0, 10.0); gsl_matrix_set(A, 0, 1, 5.0); gsl_matrix_set(A, 0, 2, 1.0); gsl_matrix_set(A, 1, 0, 1.0); gsl_matrix_set(A, 1, 1, 20.0); gsl_matrix_set(A, 1, 2, 5.0); gsl_matrix_set(A, 2, 0, 1.0); gsl_matrix_set(A, 2, 1, 3.0); gsl_matrix_set(A, 2, 2, 7.0); gsl_matrix_set(B, 0, 0, 10.0); gsl_matrix_set(B, 0, 1, 5.0); gsl_matrix_set(B, 0, 2, 2.0); gsl_matrix_set(B, 1, 0, 1.0); gsl_matrix_set(B, 1, 1, 3.0); gsl_matrix_set(B, 1, 2, 2.0); gsl_matrix_set(B, 2, 0, 1.0); gsl_matrix_set(B, 2, 1, 3.0); gsl_matrix_set(B, 2, 2, 2.0); gsl_matrix_set(D, 0, 0, 10.0); gsl_matrix_set(D, 0, 1, 5.0); gsl_matrix_set(D, 0, 2, 1.0); gsl_matrix_set(D, 1, 0, 1.0); gsl_matrix_set(D, 1, 1, 20.0); gsl_matrix_set(D, 1, 2, 5.0); gsl_matrix_set(E, 0, 0, 10.0); gsl_matrix_set(E, 0, 1, 5.0); gsl_matrix_set(E, 0, 2, 2.0); gsl_matrix_set(E, 1, 0, 1.0); gsl_matrix_set(E, 1, 1, 3.0); gsl_matrix_set(E, 1, 2, 2.0); gsl_linalg_matmult_mod(A, GSL_LINALG_MOD_NONE, B, GSL_LINALG_MOD_NONE, C); s += ( fabs(gsl_matrix_get(C, 0, 0) - 106.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 1) - 68.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 2) - 32.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 0) - 35.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 1) - 80.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 2) - 52.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 0) - 20.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 1) - 35.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 2) - 22.0) > GSL_DBL_EPSILON ); gsl_linalg_matmult_mod(A, GSL_LINALG_MOD_TRANSPOSE, B, GSL_LINALG_MOD_NONE, C); s += ( fabs(gsl_matrix_get(C, 0, 0) - 102.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 1) - 56.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 2) - 24.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 0) - 73.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 1) - 94.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 2) - 56.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 0) - 22.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 1) - 41.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 2) - 26.0) > GSL_DBL_EPSILON ); gsl_linalg_matmult_mod(A, GSL_LINALG_MOD_NONE, B, GSL_LINALG_MOD_TRANSPOSE, C); s += ( fabs(gsl_matrix_get(C, 0, 0) - 127.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 1) - 27.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 2) - 27.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 0) - 120.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 1) - 71.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 2) - 71.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 0) - 39.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 1) - 24.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 2) - 24.0) > GSL_DBL_EPSILON ); gsl_linalg_matmult_mod(A, GSL_LINALG_MOD_TRANSPOSE, B, GSL_LINALG_MOD_TRANSPOSE, C); s += ( fabs(gsl_matrix_get(C, 0, 0) - 107.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 1) - 15.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 2) - 15.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 0) - 156.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 1) - 71.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 2) - 71.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 0) - 49.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 1) - 30.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 2) - 30.0) > GSL_DBL_EPSILON ); /* now try for non-symmetric matrices */ gsl_linalg_matmult_mod(D, GSL_LINALG_MOD_TRANSPOSE, E, GSL_LINALG_MOD_NONE, C); s += ( fabs(gsl_matrix_get(C, 0, 0) - 101.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 1) - 53.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 0, 2) - 22.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 0) - 70.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 1) - 85.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 1, 2) - 50.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 0) - 15.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 1) - 20.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(C, 2, 2) - 12.0) > GSL_DBL_EPSILON ); gsl_linalg_matmult_mod(D, GSL_LINALG_MOD_NONE, E, GSL_LINALG_MOD_TRANSPOSE, F); s += ( fabs(gsl_matrix_get(F, 0, 0) - 127.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(F, 0, 1) - 27.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(F, 1, 0) - 120.0) > GSL_DBL_EPSILON ); s += ( fabs(gsl_matrix_get(F, 1, 1) - 71.0) > GSL_DBL_EPSILON ); gsl_matrix_free(A); gsl_matrix_free(B); gsl_matrix_free(C); gsl_matrix_free(D); gsl_matrix_free(E); gsl_matrix_free(F); return s; } #endif int test_LU_solve_dim(const gsl_matrix * m, const double * actual, double eps) { int s = 0; int signum; unsigned long i, dim = m->size1; gsl_permutation * perm = gsl_permutation_alloc(dim); gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * lu = gsl_matrix_alloc(dim,dim); gsl_vector * x = gsl_vector_alloc(dim); gsl_vector * residual = gsl_vector_alloc(dim); gsl_matrix_memcpy(lu,m); for(i=0; isize1; gsl_permutation * perm = gsl_permutation_alloc(dim); gsl_vector_complex * rhs = gsl_vector_complex_alloc(dim); gsl_matrix_complex * lu = gsl_matrix_complex_alloc(dim,dim); gsl_vector_complex * x = gsl_vector_complex_alloc(dim); gsl_vector_complex * residual = gsl_vector_complex_alloc(dim); gsl_matrix_complex_memcpy(lu,m); for(i=0; isize1; gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * qr = gsl_matrix_alloc(dim,dim); gsl_vector * d = gsl_vector_alloc(dim); gsl_vector * x = gsl_vector_alloc(dim); gsl_matrix_memcpy(qr,m); for(i=0; isize1; gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * qr = gsl_matrix_alloc(dim,dim); gsl_matrix * q = gsl_matrix_alloc(dim,dim); gsl_matrix * r = gsl_matrix_alloc(dim,dim); gsl_vector * d = gsl_vector_alloc(dim); gsl_vector * x = gsl_vector_alloc(dim); gsl_matrix_memcpy(qr,m); for(i=0; isize1, N = m->size2; gsl_vector * rhs = gsl_vector_alloc(M); gsl_matrix * qr = gsl_matrix_alloc(M,N); gsl_vector * d = gsl_vector_alloc(N); gsl_vector * x = gsl_vector_alloc(N); gsl_vector * r = gsl_vector_alloc(M); gsl_vector * res = gsl_vector_alloc(M); gsl_matrix_memcpy(qr,m); for(i=0; isize1, N = m->size2; gsl_matrix * qr = gsl_matrix_alloc(M,N); gsl_matrix * a = gsl_matrix_alloc(M,N); gsl_matrix * q = gsl_matrix_alloc(M,M); gsl_matrix * r = gsl_matrix_alloc(M,N); gsl_vector * d = gsl_vector_alloc(GSL_MIN(M,N)); gsl_matrix_memcpy(qr,m); s += gsl_linalg_QR_decomp(qr, d); s += gsl_linalg_QR_unpack(qr, d, q, r); /* compute a = q r */ gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, q, r, 0.0, a); for(i=0; isize1; gsl_permutation * perm = gsl_permutation_alloc(dim); gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * qr = gsl_matrix_alloc(dim,dim); gsl_vector * d = gsl_vector_alloc(dim); gsl_vector * x = gsl_vector_alloc(dim); gsl_vector * norm = gsl_vector_alloc(dim); gsl_matrix_memcpy(qr,m); for(i=0; isize1; gsl_permutation * perm = gsl_permutation_alloc(dim); gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * qr = gsl_matrix_alloc(dim,dim); gsl_matrix * q = gsl_matrix_alloc(dim,dim); gsl_matrix * r = gsl_matrix_alloc(dim,dim); gsl_vector * d = gsl_vector_alloc(dim); gsl_vector * x = gsl_vector_alloc(dim); gsl_vector * norm = gsl_vector_alloc(dim); gsl_matrix_memcpy(qr,m); for(i=0; isize1, N = m->size2; gsl_matrix * qr = gsl_matrix_alloc(M,N); gsl_matrix * a = gsl_matrix_alloc(M,N); gsl_matrix * q = gsl_matrix_alloc(M,M); gsl_matrix * r = gsl_matrix_alloc(M,N); gsl_vector * d = gsl_vector_alloc(GSL_MIN(M,N)); gsl_vector * norm = gsl_vector_alloc(N); gsl_permutation * perm = gsl_permutation_alloc(N); gsl_matrix_memcpy(qr,m); s += gsl_linalg_QRPT_decomp(qr, d, perm, &signum, norm); s += gsl_linalg_QR_unpack(qr, d, q, r); /* compute a = q r */ gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, q, r, 0.0, a); /* Compute QR P^T by permuting the elements of the rows of QR */ for (i = 0; i < M; i++) { gsl_vector_view row = gsl_matrix_row (a, i); gsl_permute_vector_inverse (perm, &row.vector); } for(i=0; isize1, N = m->size2; gsl_vector * rhs = gsl_vector_alloc(N); gsl_matrix * qr1 = gsl_matrix_alloc(M,N); gsl_matrix * qr2 = gsl_matrix_alloc(M,N); gsl_matrix * q1 = gsl_matrix_alloc(M,M); gsl_matrix * r1 = gsl_matrix_alloc(M,N); gsl_matrix * q2 = gsl_matrix_alloc(M,M); gsl_matrix * r2 = gsl_matrix_alloc(M,N); gsl_vector * d = gsl_vector_alloc(GSL_MIN(M,N)); gsl_vector * solution1 = gsl_vector_alloc(N); gsl_vector * solution2 = gsl_vector_alloc(N); gsl_vector * u = gsl_vector_alloc(M); gsl_vector * v = gsl_vector_alloc(N); gsl_vector * w = gsl_vector_alloc(M); gsl_matrix_memcpy(qr1,m); gsl_matrix_memcpy(qr2,m); for(i=0; isize1; gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * lq = gsl_matrix_alloc(dim,dim); gsl_vector * d = gsl_vector_alloc(dim); gsl_vector * x = gsl_vector_alloc(dim); gsl_matrix_transpose_memcpy(lq,m); for(i=0; isize1; gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * lq = gsl_matrix_alloc(dim,dim); gsl_matrix * q = gsl_matrix_alloc(dim,dim); gsl_matrix * l = gsl_matrix_alloc(dim,dim); gsl_vector * d = gsl_vector_alloc(dim); gsl_vector * x = gsl_vector_alloc(dim); gsl_matrix_transpose_memcpy(lq,m); for(i=0; isize1, N = m->size2; gsl_vector * rhs = gsl_vector_alloc(M); gsl_matrix * lq = gsl_matrix_alloc(N,M); gsl_vector * d = gsl_vector_alloc(N); gsl_vector * x = gsl_vector_alloc(N); gsl_vector * r = gsl_vector_alloc(M); gsl_vector * res = gsl_vector_alloc(M); gsl_matrix_transpose_memcpy(lq,m); for(i=0; isize1, N = m->size2; gsl_matrix * lq = gsl_matrix_alloc(M,N); gsl_matrix * a = gsl_matrix_alloc(M,N); gsl_matrix * q = gsl_matrix_alloc(N,N); gsl_matrix * l = gsl_matrix_alloc(M,N); gsl_vector * d = gsl_vector_alloc(GSL_MIN(M,N)); gsl_matrix_memcpy(lq,m); s += gsl_linalg_LQ_decomp(lq, d); s += gsl_linalg_LQ_unpack(lq, d, q, l); /* compute a = q r */ gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, l, q, 0.0, a); for(i=0; isize1; gsl_permutation * perm = gsl_permutation_alloc(dim); gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * lq = gsl_matrix_alloc(dim,dim); gsl_vector * d = gsl_vector_alloc(dim); gsl_vector * x = gsl_vector_alloc(dim); gsl_vector * norm = gsl_vector_alloc(dim); gsl_matrix_transpose_memcpy(lq,m); for(i=0; isize1; gsl_permutation * perm = gsl_permutation_alloc(dim); gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * lq = gsl_matrix_alloc(dim,dim); gsl_matrix * q = gsl_matrix_alloc(dim,dim); gsl_matrix * l = gsl_matrix_alloc(dim,dim); gsl_vector * d = gsl_vector_alloc(dim); gsl_vector * x = gsl_vector_alloc(dim); gsl_vector * norm = gsl_vector_alloc(dim); gsl_matrix_transpose_memcpy(lq,m); for(i=0; isize1, N = m->size2; gsl_matrix * lq = gsl_matrix_alloc(N,M); gsl_matrix * a = gsl_matrix_alloc(N,M); gsl_matrix * q = gsl_matrix_alloc(M,M); gsl_matrix * l = gsl_matrix_alloc(N,M); gsl_vector * d = gsl_vector_alloc(GSL_MIN(M,N)); gsl_vector * norm = gsl_vector_alloc(N); gsl_permutation * perm = gsl_permutation_alloc(N); gsl_matrix_transpose_memcpy(lq,m); s += gsl_linalg_PTLQ_decomp(lq, d, perm, &signum, norm); s += gsl_linalg_LQ_unpack(lq, d, q, l); /* compute a = l q */ gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, l, q, 0.0, a); /* Compute P LQ by permuting the rows of LQ */ for (i = 0; i < M; i++) { gsl_vector_view col = gsl_matrix_column (a, i); gsl_permute_vector_inverse (perm, &col.vector); } for(i=0; isize1, N = m->size2; gsl_matrix * lq1 = gsl_matrix_alloc(N,M); gsl_matrix * lq2 = gsl_matrix_alloc(N,M); gsl_matrix * q1 = gsl_matrix_alloc(M,M); gsl_matrix * l1 = gsl_matrix_alloc(N,M); gsl_matrix * q2 = gsl_matrix_alloc(M,M); gsl_matrix * l2 = gsl_matrix_alloc(N,M); gsl_vector * d2 = gsl_vector_alloc(GSL_MIN(M,N)); gsl_vector * u = gsl_vector_alloc(M); gsl_vector * v = gsl_vector_alloc(N); gsl_vector * w = gsl_vector_alloc(M); gsl_matrix_transpose_memcpy(lq1,m); gsl_matrix_transpose_memcpy(lq2,m); for(i=0; isize1; gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * u = gsl_matrix_alloc(dim,dim); gsl_matrix * q = gsl_matrix_alloc(dim,dim); gsl_vector * d = gsl_vector_alloc(dim); gsl_vector * x = gsl_vector_calloc(dim); gsl_matrix_memcpy(u,m); for(i=0; isize1, N = m->size2; gsl_matrix * v = gsl_matrix_alloc(M,N); gsl_matrix * a = gsl_matrix_alloc(M,N); gsl_matrix * q = gsl_matrix_alloc(N,N); gsl_matrix * dqt = gsl_matrix_alloc(N,N); gsl_vector * d = gsl_vector_alloc(N); gsl_vector * w = gsl_vector_alloc(N); gsl_matrix_memcpy(v,m); s += gsl_linalg_SV_decomp(v, q, d, w); /* Check that singular values are non-negative and in non-decreasing order */ di1 = 0.0; for (i = 0; i < N; i++) { double di = gsl_vector_get (d, i); if (gsl_isnan (di)) { continue; /* skip NaNs */ } if (di < 0) { s++; printf("singular value %lu = %22.18g < 0\n", i, di); } if(i > 0 && di > di1) { s++; printf("singular value %lu = %22.18g vs previous %22.18g\n", i, di, di1); } di1 = di; } /* Scale dqt = D Q^T */ for (i = 0; i < N ; i++) { double di = gsl_vector_get (d, i); for (j = 0; j < N; j++) { double qji = gsl_matrix_get(q, j, i); gsl_matrix_set (dqt, i, j, qji * di); } } /* compute a = v dqt */ gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, v, dqt, 0.0, a); for(i=0; idata; for (i=0; i<9; i++) { a[i] = lower; } while (carry == 0.0) { f = test_SV_decomp_dim(A33, 64 * GSL_DBL_EPSILON); gsl_test(f, " SV_decomp (3x3) A=[ %g, %g, %g; %g, %g, %g; %g, %g, %g]", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); /* increment */ carry=1.0; for (i=9; carry > 0.0 && i>0 && i--;) { double v=a[i]+carry; carry = (v>upper) ? 1.0 : 0.0; a[i] = (v>upper) ? lower : v; } } } #ifdef TEST_SVD_4X4 { int i; double carry = 0, lower = 0, upper = 1; double *a = A44->data; for (i=0; i<16; i++) { a[i] = lower; } while (carry == 0.0) { f = test_SV_decomp_dim(A44, 64 * GSL_DBL_EPSILON); gsl_test(f, " SV_decomp (4x4) A=[ %g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g]", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); /* increment */ carry=1.0; for (i=16; carry > 0.0 && i>0 && i--;) { double v=a[i]+carry; carry = (v>upper) ? 1.0 : 0.0; a[i] = (v>upper) ? lower : v; } } } #endif return s; } int test_SV_decomp_mod_dim(const gsl_matrix * m, double eps) { int s = 0; double di1; unsigned long i,j, M = m->size1, N = m->size2; gsl_matrix * v = gsl_matrix_alloc(M,N); gsl_matrix * a = gsl_matrix_alloc(M,N); gsl_matrix * q = gsl_matrix_alloc(N,N); gsl_matrix * x = gsl_matrix_alloc(N,N); gsl_matrix * dqt = gsl_matrix_alloc(N,N); gsl_vector * d = gsl_vector_alloc(N); gsl_vector * w = gsl_vector_alloc(N); gsl_matrix_memcpy(v,m); s += gsl_linalg_SV_decomp_mod(v, x, q, d, w); /* Check that singular values are non-negative and in non-decreasing order */ di1 = 0.0; for (i = 0; i < N; i++) { double di = gsl_vector_get (d, i); if (gsl_isnan (di)) { continue; /* skip NaNs */ } if (di < 0) { s++; printf("singular value %lu = %22.18g < 0\n", i, di); } if(i > 0 && di > di1) { s++; printf("singular value %lu = %22.18g vs previous %22.18g\n", i, di, di1); } di1 = di; } /* Scale dqt = D Q^T */ for (i = 0; i < N ; i++) { double di = gsl_vector_get (d, i); for (j = 0; j < N; j++) { double qji = gsl_matrix_get(q, j, i); gsl_matrix_set (dqt, i, j, qji * di); } } /* compute a = v dqt */ gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, v, dqt, 0.0, a); for(i=0; idata; for (i=0; i<9; i++) { a[i] = lower; } while (carry == 0.0) { f = test_SV_decomp_mod_dim(A33, 64 * GSL_DBL_EPSILON); gsl_test(f, " SV_decomp_mod (3x3) A=[ %g, %g, %g; %g, %g, %g; %g, %g, %g]", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); /* increment */ carry=1.0; for (i=9; carry > 0.0 && i>0 && i--;) { double v=a[i]+carry; carry = (v>upper) ? 1.0 : 0.0; a[i] = (v>upper) ? lower : v; } } } #ifdef TEST_SVD_4X4 { int i; double carry = 0, lower = 0, upper = 1; double *a = A44->data; for (i=0; i<16; i++) { a[i] = lower; } while (carry == 0.0) { f = test_SV_decomp_mod_dim(A44, 64 * GSL_DBL_EPSILON); gsl_test(f, " SV_decomp_mod (4x4) A=[ %g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g]", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); /* increment */ carry=1.0; for (i=16; carry>0.0 && i>0 && i--;) { double v=a[i]+carry; carry = (v>upper) ? 1.0 : 0.0; a[i] = (v>upper) ? lower : v; } } } #endif return s; } int test_SV_decomp_jacobi_dim(const gsl_matrix * m, double eps) { int s = 0; double di1; unsigned long i,j, M = m->size1, N = m->size2; gsl_matrix * v = gsl_matrix_alloc(M,N); gsl_matrix * a = gsl_matrix_alloc(M,N); gsl_matrix * q = gsl_matrix_alloc(N,N); gsl_matrix * dqt = gsl_matrix_alloc(N,N); gsl_vector * d = gsl_vector_alloc(N); gsl_matrix_memcpy(v,m); s += gsl_linalg_SV_decomp_jacobi(v, q, d); if (s) printf("call returned status = %d\n", s); /* Check that singular values are non-negative and in non-decreasing order */ di1 = 0.0; for (i = 0; i < N; i++) { double di = gsl_vector_get (d, i); if (gsl_isnan (di)) { continue; /* skip NaNs */ } if (di < 0) { s++; printf("singular value %lu = %22.18g < 0\n", i, di); } if(i > 0 && di > di1) { s++; printf("singular value %lu = %22.18g vs previous %22.18g\n", i, di, di1); } di1 = di; } /* Scale dqt = D Q^T */ for (i = 0; i < N ; i++) { double di = gsl_vector_get (d, i); for (j = 0; j < N; j++) { double qji = gsl_matrix_get(q, j, i); gsl_matrix_set (dqt, i, j, qji * di); } } /* compute a = v dqt */ gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, v, dqt, 0.0, a); for(i=0; idata; for (i=0; i<9; i++) { a[i] = lower; } while (carry == 0.0) { f = test_SV_decomp_jacobi_dim(A33, 64 * GSL_DBL_EPSILON); gsl_test(f, " SV_decomp_jacobi (3x3) A=[ %g, %g, %g; %g, %g, %g; %g, %g, %g]", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); /* increment */ carry=1.0; for (i=9; carry > 0.0 && i>0 && i--;) { double v=a[i]+carry; carry = (v>upper) ? 1.0 : 0.0; a[i] = (v>upper) ? lower : v; } } } #ifdef TEST_SVD_4X4 { int i; unsigned long k = 0; double carry = 0, lower = 0, upper = 1; double *a = A44->data; for (i=0; i<16; i++) { a[i] = lower; } while (carry == 0.0) { k++; f = test_SV_decomp_jacobi_dim(A44, 64 * GSL_DBL_EPSILON); gsl_test(f, " SV_decomp_jacobi (4x4) A=[ %g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g] %lu", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], k); /* increment */ carry=1.0; for (i=16; carry > 0.0 && i>0 && i--;) { double v=a[i]+carry; carry = (v>upper) ? 1.0 : 0.0; a[i] = (v>upper) ? lower : v; } } } #endif { int i; unsigned long k = 0; double carry = 0, lower = 0, upper = 1; double *a = A55->data; for (i=0; i<25; i++) { a[i] = lower; } while (carry == 0.0) { k++; if (k % 1001 == 0) { f = test_SV_decomp_jacobi_dim(A55, 64 * GSL_DBL_EPSILON); gsl_test(f, " SV_decomp_jacobi (5x5) case=%lu",k); } /* increment */ carry=1.0; for (i=25; carry >0.0 && i>0 && i--;) { double v=a[i]+carry; carry = (v>upper) ? 1.0 : 0.0; a[i] = (v>upper) ? lower : v; } } } return s; } int test_cholesky_solve_dim(const gsl_matrix * m, const double * actual, double eps) { int s = 0; unsigned long i, dim = m->size1; gsl_vector * rhs = gsl_vector_alloc(dim); gsl_matrix * u = gsl_matrix_alloc(dim,dim); gsl_vector * x = gsl_vector_calloc(dim); gsl_matrix_memcpy(u,m); for(i=0; isize1, N = m->size2; gsl_matrix * v = gsl_matrix_alloc(M,N); gsl_matrix * a = gsl_matrix_alloc(M,N); gsl_matrix * l = gsl_matrix_alloc(M,N); gsl_matrix * lt = gsl_matrix_alloc(N,N); gsl_matrix_memcpy(v,m); s += gsl_linalg_cholesky_decomp(v); /* Compute L LT */ for (i = 0; i < N ; i++) { for (j = 0; j < N; j++) { double vij = gsl_matrix_get(v, i, j); gsl_matrix_set (l, i, j, i>=j ? vij : 0); gsl_matrix_set (lt, i, j, i<=j ? vij : 0); } } /* compute a = l lt */ gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, l, lt, 0.0, a); for(i=0; isize1; const unsigned long N = m->size2; unsigned long i,j; gsl_matrix * v = gsl_matrix_alloc(M,N); gsl_matrix * a = gsl_matrix_alloc(M,N); gsl_matrix * l = gsl_matrix_alloc(M,N); gsl_matrix * lt = gsl_matrix_alloc(N,N); gsl_matrix * dm = gsl_matrix_alloc(M,N); gsl_vector * dv = gsl_vector_alloc(M); gsl_matrix_memcpy(v,m); s += gsl_linalg_cholesky_decomp_unit(v, dv); /* for(i = 0; i < M; i++) { for(j = 0; j < N; j++) { printf("v[%lu,%lu]: %22.18e\n", i,j, gsl_matrix_get(v, i, j)); } } for(i = 0; i < M; i++) { printf("d[%lu]: %22.18e\n", i, gsl_vector_get(dv, i)); } */ /* put L and transpose(L) into separate matrices */ for(i = 0; i < N ; i++) { for(j = 0; j < N; j++) { const double vij = gsl_matrix_get(v, i, j); gsl_matrix_set (l, i, j, i>=j ? vij : 0); gsl_matrix_set (lt, i, j, i<=j ? vij : 0); } } /* put D into its own matrix */ gsl_matrix_set_zero(dm); for(i = 0; i < M; ++i) gsl_matrix_set(dm, i, i, gsl_vector_get(dv, i)); /* compute a = L * D * transpose(L); uses v for temp space */ gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, dm, lt, 0.0, v); gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, l, v, 0.0, a); for(i = 0; i < M; i++) { for(j = 0; j < N; j++) { const double aij = gsl_matrix_get(a, i, j); const double mij = gsl_matrix_get(m, i, j); int foo = check(aij, mij, eps); if(foo) { printf("(%3lu,%3lu)[%lu,%lu]: %22.18g %22.18g\n", M, N, i,j, aij, mij); } s += foo; } } gsl_vector_free(dv); gsl_matrix_free(dm); gsl_matrix_free(lt); gsl_matrix_free(l); gsl_matrix_free(v); gsl_matrix_free(a); return s; } int test_cholesky_decomp_unit(void) { int f; int s = 0; f = test_cholesky_decomp_unit_dim(hilb2, 2 * 8.0 * GSL_DBL_EPSILON); gsl_test(f, " cholesky_decomp_unit hilbert(2)"); s += f; f = test_cholesky_decomp_unit_dim(hilb3, 2 * 64.0 * GSL_DBL_EPSILON); gsl_test(f, " cholesky_decomp_unit hilbert(3)"); s += f; f = test_cholesky_decomp_unit_dim(hilb4, 2 * 1024.0 * GSL_DBL_EPSILON); gsl_test(f, " cholesky_decomp_unit hilbert(4)"); s += f; f = test_cholesky_decomp_unit_dim(hilb12, 2 * 1024.0 * GSL_DBL_EPSILON); gsl_test(f, " cholesky_decomp_unit hilbert(12)"); s += f; return s; } int test_HH_solve_dim(const gsl_matrix * m, const double * actual, double eps) { int s = 0; unsigned long i, dim = m->size1; gsl_permutation * perm = gsl_permutation_alloc(dim); gsl_matrix * hh = gsl_matrix_alloc(dim,dim); gsl_vector * d = gsl_vector_alloc(dim); gsl_vector * x = gsl_vector_alloc(dim); gsl_matrix_memcpy(hh,m); for(i=0; isize1, N = m->size2; gsl_matrix * A = gsl_matrix_alloc(M,N); gsl_matrix * a = gsl_matrix_alloc(M,N); gsl_matrix * b = gsl_matrix_alloc(N,N); gsl_matrix * u = gsl_matrix_alloc(M,N); gsl_matrix * v = gsl_matrix_alloc(N,N); gsl_vector * tau1 = gsl_vector_alloc(N); gsl_vector * tau2 = gsl_vector_alloc(N-1); gsl_vector * d = gsl_vector_alloc(N); gsl_vector * sd = gsl_vector_alloc(N-1); gsl_matrix_memcpy(A,m); s += gsl_linalg_bidiag_decomp(A, tau1, tau2); s += gsl_linalg_bidiag_unpack(A, tau1, u, tau2, v, d, sd); gsl_matrix_set_zero(b); for (i = 0; i < N; i++) gsl_matrix_set(b, i,i, gsl_vector_get(d,i)); for (i = 0; i < N-1; i++) gsl_matrix_set(b, i,i+1, gsl_vector_get(sd,i)); /* Compute A = U B V^T */ for (i = 0; i < M ; i++) { for (j = 0; j < N; j++) { double sum = 0; for (k = 0; k < N; k++) { for (r = 0; r < N; r++) { sum += gsl_matrix_get(u, i, k) * gsl_matrix_get (b, k, r) * gsl_matrix_get(v, j, r); } } gsl_matrix_set (a, i, j, sum); } } for(i=0; i