home *** CD-ROM | disk | FTP | other *** search
- [cf MACHEPS = %g]\n",
- v_norm2(u), MACHEPS);
- }
-
- Q = m_resize(Q,A->m,A->m);
- makeQ(A,diag,Q);
- makeR(A,A);
- m_mlt(Q,A,C);
- M_FREE(D);
- D = m_get(B->m,B->n);
- px_cols(pivot,C,D);
- m_sub(B,D,D);
- if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm1(B) )
- {
- errmesg("QRCPfactor()/makeQ()/makeR()");
- printf("# QR reconstruction error = %g [cf MACHEPS = %g]\n",
- m_norm1(D), MACHEPS);
- }
-
- MEMCHK();
-
- /* Cholesky and LDL^T factorisation */
- /* Use these for normal equations approach */
- notice("Cholesky factor/solve");
- mtrm_mlt(B,B,A);
- CHfactor(A);
- u = v_resize(u,B->n);
- vm_mlt(B,y,u);
- z = v_resize(z,B->n);
- CHsolve(A,u,z);
- v_sub(x,z,z);
- if ( v_norm2(z) >= MACHEPS*v_norm2(x)*100 )
- {
- errmesg("CHfactor()/CHsolve()");
- printf("# Cholesky solution error = %g [cf MACHEPS = %g]\n",
- v_norm2(z), MACHEPS);
- }
- /* modified Cholesky factorisation should be identical with Cholesky
- factorisation provided the matrix is "sufficiently positive definite */
- mtrm_mlt(B,B,C);
- MCHfactor(C,MACHEPS);
- m_sub(A,C,C);
- if ( m_norm1(C) >= MACHEPS*m_norm1(A) )
- {
- errmesg("MCHfactor()");
- printf("# Modified Cholesky error = %g [cf MACHEPS = %g]\n",
- m_norm1(C), MACHEPS);
- }
- /* now test the LDL^T factorisation -- using a negative def. matrix */
- mtrm_mlt(B,B,A);
- sm_mlt(-1.0,A,A);
- m_copy(A,C);
- LDLfactor(A);
- LDLsolve(A,u,z);
- w = v_get(A->m);
- mv_mlt(C,z,w);
- v_sub(w,u,w);
- if ( v_norm2(w) >= MACHEPS*v_norm2(u)*m_norm1(C) )
- {
- errmesg("LDLfactor()/LDLsolve()");
- printf("# LDL^T residual = %g [cf MACHEPS = %g]\n",
- v_norm2(w), MACHEPS);
- }
- v_add(x,z,z);
- if ( v_norm2(z) >= MACHEPS*v_norm2(x)*100 )
- {
- errmesg("LDLfactor()/LDLsolve()");
- printf("# LDL^T solution error = %g [cf MACHEPS = %g]\n",
- v_norm2(z), MACHEPS);
- }
-
- MEMCHK();
-
- /* and now the Bunch-Kaufman-Parlett method */
- /* set up D to be an indefinite diagonal matrix */
- notice("Bunch-Kaufman-Parlett factor/solve");
-
- D = m_resize(D,B->m,B->m);
- m_zero(D);
- w = v_resize(w,B->m);
- v_rand(w);
- for ( i = 0; i < w->dim; i++ )
- if ( v_entry(w,i) >= 0.5 )
- m_set_val(D,i,i,1.0);
- else
- m_set_val(D,i,i,-1.0);
- /* set A <- B^T.D.B */
- C = m_resize(C,B->n,B->n);
- C = mtrm_mlt(B,D,C);
- A = m_mlt(C,B,A);
- C = m_resize(C,B->n,B->n);
- C = m_copy(A,C);
- /* ... and use BKPfactor() */
- blocks = px_get(A->m);
- pivot = px_resize(pivot,A->m);
- x = v_resize(x,A->m);
- y = v_resize(y,A->m);
- z = v_resize(z,A->m);
- v_rand(x);
- mv_mlt(A,x,y);
- BKPfactor(A,pivot,blocks);
- printf("# BKP pivot =\n"); px_output(pivot);
- printf("# BKP blocks =\n"); px_output(blocks);
- BKPsolve(A,pivot,blocks,y,z);
- /* compute & check residual */
- mv_mlt(C,z,w);
- v_sub(w,y,w);
- if ( v_norm2(w) >= MACHEPS*m_norm1(C)*v_norm2(z) )
- {
- errmesg("BKPfactor()/BKPsolve()");
- printf("# BKP residual size = %g [cf MACHEPS = %g]\n",
- v_norm2(w), MACHEPS);
- }
-
- /* check update routines */
- /* check LDLupdate() first */
- notice("update L.D.L^T routine");
- A = mtrm_mlt(B,B,A);
- m_resize(C,A->m,A->n);
- C = m_copy(A,C);
- LDLfactor(A);
- s1 = 3.7;
- w = v_resize(w,A->m);
- v_rand(w);
- for ( i = 0; i < C->m; i++ )
- for ( j = 0; j < C->n; j++ )
- m_set_val(C,i,j,m_entry(C,i,j)+s1*v_entry(w,i)*v_entry(w,j));
- LDLfactor(C);
- LDLupdate(A,w,s1);
- /* zero out strictly upper triangular parts of A and C */
- for ( i = 0; i < A->m; i++ )
- for ( j = i+1; j < A->n; j++ )
- {
- m_set_val(A,i,j,0.0);
- m_set_val(C,i,j,0.0);
- }
- if ( m_norm1(m_sub(A,C,C)) >= sqrt(MACHEPS)*m_norm1(A) )
- {
- errmesg("LDLupdate()");
- printf("# LDL update matrix error = %g [cf MACHEPS = %g]\n",
- m_norm1(C), MACHEPS);
- }
-
-
- /* BAND MATRICES */
-
- #define COL 40
- #define UDIAG 5
- #define LDIAG 2
-
- smrand(101);
- bA = bd_get(LDIAG,UDIAG,COL);
- bB = bd_get(LDIAG,UDIAG,COL);
- bC = bd_get(LDIAG,UDIAG,COL);
- A = m_resize(A,COL,COL);
- B = m_resize(B,COL,COL);
- pivot = px_resize(pivot,COL);
- x = v_resize(x,COL);
- w = v_resize(w,COL);
- z = v_resize(z,COL);
-
- m_rand(A);
- /* generate band matrix */
- mat2band(A,LDIAG,UDIAG,bA);
- band2mat(bA,A); /* now A is banded */
- bB = bd_copy(bA,bB);
-
- v_rand(x);
- mv_mlt(A,x,w);
- z = v_copy(w,z);
-
- notice("band LU factorization");
- bdLUfactor(bA,pivot);
-
- /* pivot will be changed */
- bdLUsolve(bA,pivot,z,z);
- v_sub(x,z,z);
- if (v_norm2(z) > v_norm2(x)*sqrt(MACHEPS)) {
- errmesg("incorrect solution (band LU factorization)");
- printf(" ||exact sol. - computed sol.|| = %g [MACHEPS = %g]\n",
- v_norm2(z),MACHEPS);
- }
-
- /* solve transpose system */
-
- notice("band LU factorization for transpose system");
- m_transp(A,B);
- mv_mlt(B,x,w);
-
- bd_copy(bB,bA);
- bd_transp(bA,bA);
- /* transposition in situ */
- bd_transp(bA,bA);
- bd_transp(bA,bB);
-
- bdLUfactor(bB,pivot);
-
- bdLUsolve(bB,pivot,w,z);
- v_sub(x,z,z);
- if (v_norm2(z) > v_norm2(x)*sqrt(MACHEPS)) {
- errmesg("incorrect solution (band transposed LU factorization)");
- printf(" ||exact sol. - computed sol.|| = %g [MACHEPS = %g]\n",
- v_norm2(z),MACHEPS);
- }
-
-
- /* Cholesky factorization */
-
- notice("band Choleski LDL' factorization");
- m_add(A,B,A); /* symmetric matrix */
- for (i=0; i < COL; i++) /* positive definite */
- A->me[i][i] += 2*LDIAG;
-
- mat2band(A,LDIAG,LDIAG,bA);
- band2mat(bA,A); /* corresponding matrix A */
-
- v_rand(x);
- mv_mlt(A,x,w);
- z = v_copy(w,z);
-
- bdLDLfactor(bA);
-
- z = bdLDLsolve(bA,z,z);
- v_sub(x,z,z);
- if (v_norm2(z) > v_norm2(x)*sqrt(MACHEPS)) {
- errmesg("incorrect solution (band LDL' factorization)");
- printf(" ||exact sol. - computed sol.|| = %g [MACHEPS = %g]\n",
- v_norm2(z),MACHEPS);
- }
-
- /* new bandwidths */
- m_rand(A);
- bA = bd_resize(bA,UDIAG,LDIAG,COL);
- bB = bd_resize(bB,UDIAG,LDIAG,COL);
- mat2band(A,UDIAG,LDIAG,bA);
- band2mat(bA,A);
- bd_copy(bA,bB);
-
- mv_mlt(A,x,w);
-
- notice("band LU factorization (resized)");
- bdLUfactor(bA,pivot);
-
- /* pivot will be changed */
- bdLUsolve(bA,pivot,w,z);
- v_sub(x,z,z);
- if (v_norm2(z) > v_norm2(x)*sqrt(MACHEPS)) {
- errmesg("incorrect solution (band LU factorization)");
- printf(" ||exact sol. - computed sol.|| = %g [MACHEPS = %g]\n",
- v_norm2(z),MACHEPS);
- }
-
- /* testing transposition */
-
- notice("band matrix transposition");
- m_zero(bA->mat);
- bd_copy(bB,bA);
- m_zero(bB->mat);
- bd_copy(bA,bB);
-
- bd_transp(bB,bB);
- bd_transp(bB,bB);
-
- m_zero(bC->mat);
- bd_copy(bB,bC);
-
- m_sub(bA->mat,bC->mat,bC->mat);
- if (m_norm_inf(bC->mat) > MACHEPS*bC->mat->n) {
- errmesg("band transposition");
- printf(" difference ||A - (A')'|| = %g\n",m_norm_inf(bC->mat));
- }
-
- bd_free(bA);
- bd_free(bB);
- bd_free(bC);
-
-
- MEMCHK();
-
- /* now check QRupdate() routine */
- notice("update QR routine");
-
- B = m_resize(B,15,7);
- A = m_resize(A,B->m,B->n);
- m_copy(B,A);
- diag = v_resize(diag,A->n);
- beta = v_resize(beta,A->n);
- QRfactor(A,diag);
- Q = m_resize(Q,A->m,A->m);
- makeQ(A,diag,Q);
- makeR(A,A);
- m_resize(C,A->m,A->n);
- w = v_resize(w,A->m);
- v = v_resize(v,A->n);
- u = v_resize(u,A->m);
- v_rand(w);
- v_rand(v);
- vm_mlt(Q,w,u);
- QRupdate(Q,A,u,v);
- m_mlt(Q,A,C);
- for ( i = 0; i < B->m; i++ )
- for ( j = 0; j < B->n; j++ )
- m_set_val(B,i,j,m_entry(B,i,j)+v_entry(w,i)*v_entry(v,j));
- m_sub(B,C,C);
- if ( m_norm1(C) >= MACHEPS*m_norm1(A)*m_norm1(Q)*2 )
- {
- errmesg("QRupdate()");
- printf("# Reconstruction error in QR update = %g [cf MACHEPS = %g]\n",
- m_norm1(C), MACHEPS);
- }
- m_resize(D,Q->m,Q->n);
- mtrm_mlt(Q,Q,D);
- for ( i = 0; i < D->m; i++ )
- m_set_val(D,i,i,m_entry(D,i,i)-1.0);
- if ( m_norm1(D) >= 10*MACHEPS*m_norm1(Q)*m_norm_inf(Q) )
- {
- errmesg("QRupdate()");
- printf("# QR update orthogonality error = %g [cf MACHEPS = %g]\n",
- m_norm1(D), MACHEPS);
- }
-
- /* Now check eigenvalue/SVD routines */
- notice("eigenvalue and SVD routines");
- A = m_resize(A,11,11);
- B = m_resize(B,A->m,A->n);
- C = m_resize(C,A->m,A->n);
- D = m_resize(D,A->m,A->n);
- Q = m_resize(Q,A->m,A->n);
-
- m_rand(A);
- /* A <- A + A^T for symmetric case */
- m_add(A,m_transp(A,C),A);
- u = v_resize(u,A->m);
- u = symmeig(A,Q,u);
- m_zero(B);
- for ( i = 0; i < B->m; i++ )
- m_set_val(B,i,i,v_entry(u,i));
- m_mlt(Q,B,C);
- mmtr_mlt(C,Q,D);
- m_sub(A,D,D);
- if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q)*v_norm_inf(u)*3 )
- {
- errmesg("symmeig()");
- printf("# Reconstruction error = %g [cf MACHEPS = %g]\n",
- m_norm1(D), MACHEPS);
- }
- mtrm_mlt(Q,Q,D);
- for ( i = 0; i < D->m; i++ )
- m_set_val(D,i,i,m_entry(D,i,i)-1.0);
- if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q)*3 )
- {
- errmesg("symmeig()");
- printf("# symmeig() orthogonality error = %g [cf MACHEPS = %g]\n",
- m_norm1(D), MACHEPS);
- }
-
- MEMCHK();
-
- /* now test (real) Schur decomposition */
- /* m_copy(A,B); */
- M_FREE(A);
- A = m_get(11,11);
- m_rand(A);
- B = m_copy(A,B);
- MEMCHK();
-
- B = schur(B,Q);
- MEMCHK();
-
- m_mlt(Q,B,C);
- mmtr_mlt(C,Q,D);
- MEMCHK();
- m_sub(A,D,D);
- if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q)*m_norm1(B)*5 )
- {
- errmesg("schur()");
- printf("# Schur reconstruction error = %g [cf MACHEPS = %g]\n",
- m_norm1(D), MACHEPS);
- }
-
- /* orthogonality check */
- mmtr_mlt(Q,Q,D);
- for ( i = 0; i < D->m; i++ )
- m_set_val(D,i,i,m_entry(D,i,i)-1.0);
- if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q)*10 )
- {
- errmesg("schur()");
- printf("# Schur orthogonality error = %g [cf MACHEPS = %g]\n",
- m_norm1(D), MACHEPS);
- }
-
- MEMCHK();
-
- /* check for termination */
- Atmp = m_get(2,2);
- Qtmp = m_get(2,2);
- /* this is a 2 x 2 matrix with real eigenvalues */
- Atmp->me[0][0] = 1;
- Atmp->me[1][1] = 1;
- Atmp->me[0][1] = 4;
- Atmp->me[1][0] = 1;
- schur(Atmp,Qtmp);
-
- MEMCHK();
-
- /* now test SVD */
- A = m_resize(A,11,7);
- m_rand(A);
- U = m_get(A->n,A->n);
- Q = m_resize(Q,A->m,A->m);
- u = v_resize(u,max(A->m,A->n));
- svd(A,Q,U,u);
- /* check reconstruction of A */
- D = m_resize(D,A->m,A->n);
- C = m_resize(C,A->m,A->n);
- m_zero(D);
- for ( i = 0; i < min(A->m,A->n); i++ )
- m_set_val(D,i,i,v_entry(u,i));
- mtrm_mlt(Q,D,C);
- m_mlt(C,U,D);
- m_sub(A,D,D);
- if ( m_norm1(D) >= MACHEPS*m_norm1(U)*m_norm_inf(Q)*m_norm1(A) )
- {
- errmesg("svd()");
- printf("# SVD reconstruction error = %g [cf MACHEPS = %g]\n",
- m_norm1(D), MACHEPS);
- }
- /* check orthogonality of Q and U */
- D = m_resize(D,Q->n,Q->n);
- mtrm_mlt(Q,Q,D);
- for ( i = 0; i < D->m; i++ )
- m_set_val(D,i,i,m_entry(D,i,i)-1.0);
- if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q)*5 )
- {
- errmesg("svd()");
- printf("# SVD orthognality error (Q) = %g [cf MACHEPS = %g\n",
- m_norm1(D), MACHEPS);
- }
- D = m_resize(D,U->n,U->n);
- mtrm_mlt(U,U,D);
- for ( i = 0; i < D->m; i++ )
- m_set_val(D,i,i,m_entry(D,i,i)-1.0);
- if ( m_norm1(D) >= MACHEPS*m_norm1(U)*m_norm_inf(U)*5 )
- {
- errmesg("svd()");
- printf("# SVD orthognality error (U) = %g [cf MACHEPS = %g\n",
- m_norm1(D), MACHEPS);
- }
- for ( i = 0; i < u->dim; i++ )
- if ( v_entry(u,i) < 0 || (i < u->dim-1 &&
- v_entry(u,i+1) > v_entry(u,i)) )
- break;
- if ( i < u->dim )
- {
- errmesg("svd()");
- printf("# SVD sorting error\n");
- }
-
-
- /* test of long vectors */
- notice("Long vectors");
- x = v_resize(x,100000);
- y = v_resize(y,100000);
- z = v_resize(z,100000);
- v_rand(x);
- v_rand(y);
- v_mltadd(x,y,3.0,z);
- sv_mlt(1.0/3.0,z,z);
- v_mltadd(z,x,-1.0/3.0,z);
- v_sub(z,y,x);
- if (v_norm2(x) >= MACHEPS*(x->dim)) {
- errmesg("long vectors");
- printf(" norm = %g\n",v_norm2(x));
- }
-
- mem_stat_free(1);
-
- MEMCHK();
-
- /**************************************************
- VEC *x, *y, *z, *u, *v, *w;
- VEC *diag, *beta;
- PERM *pi1, *pi2, *pi3, *pivot, *blocks;
- MAT *A, *B, *C, *D, *Q, *U;
- **************************************************/
- V_FREE(x); V_FREE(y); V_FREE(z);
- V_FREE(u); V_FREE(v); V_FREE(w);
- V_FREE(diag); V_FREE(beta);
- PX_FREE(pi1); PX_FREE(pi2); PX_FREE(pi3);
- PX_FREE(pivot); PX_FREE(blocks);
- M_FREE(A); M_FREE(B); M_FREE(C);
- M_FREE(D); M_FREE(Q); M_FREE(U);
- M_FREE(Atmp); M_FREE(Qtmp);
-
- MEMCHK();
- printf("# Finished torture test\n");
- mem_info();
-
- return 0;
- }
-
- FileDataŵtutadv † Eÿÿÿ@ò X Â
- /* routines from the section 8 of tutorial.txt */
-
- #include "matrix.h"
-
- #define M3D_LIST 3 /* list number */
- #define TYPE_MAT3D 0 /* the number of a type */
-
- /* type for 3 dimensional matrices */
- typedef struct {
- int l,m,n; /* actual dimensions */
- int max_l, max_m, max_n; /* maximal dimensions */
- Real ***me; /* pointer to matrix elements */
- /* we do not consider segmented memory */
- Real *base, **me2d; /* me and me2d are additional pointers
- to base */
- } MAT3D;
-
-
- /* function for creating a variable of MAT3D type */
-
- MAT3D