itertort.c

来自「C语言版本的矩阵库」· C语言 代码 · 共 692 行 · 第 1/2 页

C
692
字号
   v_rand(v);
   v = iter_spcgs(An,NULL,yn,u,EPS,v,1000,&k);

   mem_stat_free(1);
   printf(" cgs: no. of iter.steps = %d\n",k);
   v_sub(v,xn,u);
   printf(" (cgs:) ||u_ex - u_approx||_2 = %g  [EPS = %g]\n",
	  v_norm2(u),EPS);
   


   /*** LSQR ***/

   notice("LSQR method (without preconditioning)");

   v_rand(u);
   v_free(ipns1->x);
   ipns1->x = u;
   ipns1->shared_x = TRUE;
   ipns1->info = NULL;
   mem_stat_mark(2);
   z = iter_lsqr(ipns1);
   
   v_sub(xn,z,v);
   k = ipns1->steps;
   printf(" lsqr: # of iter. steps = %d\n",k);
   printf(" (lsqr:) ||u_ex - u_approx||_2 = %g  [EPS = %g]\n",
	  v_norm2(v),EPS);

   v_rand(u);
   u = iter_splsqr(An,yn,EPS,u,1000,&k);
   mem_stat_free(2);
   
   v_sub(xn,u,v);
   printf(" splsqr: # of iter. steps = %d\n",k);
   printf(" (splsqr:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n",	
	  v_norm2(v),EPS);



   /***** GMRES ********/

   notice("GMRES method with ICH preconditioning (nonsymmetric case)");

   v_zero(ipns->x);
/*   ipns->info = iter_std_info;  */
   ipns->info = NULL;  

   mem_stat_mark(2);
   z = iter_gmres(ipns);
   v_sub(xn,z,v);
   k = ipns->steps;
   printf(" gmres: # of iter. steps = %d\n",k);
   printf(" (gmres:) ||u_ex - u_approx||_2 = %g  [EPS = %g]\n",
	  v_norm2(v),EPS);

   notice("GMRES method without preconditioning (nonsymmetric case)");
   V_FREE(v);
   v = iter_spgmres(An,NULL,yn,EPS,VNULL,10,1004,&k);
   mem_stat_free(2);
   
   v_sub(xn,v,v);
   printf(" spgmres: # of iter. steps = %d\n",k);
   printf(" (spgmres:) ||u_ex - u_approx||_2 = %g  [EPS = %g]\n",
	  v_norm2(v),EPS);



   /**** MGCR *****/

   notice("MGCR method with ICH preconditioning (nonsymmetric case)");

   v_zero(ipns->x);
   mem_stat_mark(2);
   z = iter_mgcr(ipns);
   v_sub(xn,z,v);
   k = ipns->steps;
   printf(" mgcr: # of iter. steps = %d\n",k);
   printf(" (mgcr:) ||u_ex - u_approx||_2 = %g  [EPS = %g]\n",
	  v_norm2(v),EPS);

   notice("MGCR method without  preconditioning (nonsymmetric case)");
   V_FREE(v);
   v = iter_spmgcr(An,NULL,yn,EPS,VNULL,10,1004,&k);
   mem_stat_free(2);
   
   v_sub(xn,v,v);
   printf(" spmgcr: # of iter. steps = %d\n",k);
   printf(" (spmgcr:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n",
	  v_norm2(v),EPS);


   /***** ARNOLDI METHOD ********/


   notice("arnoldi method");

   kk = ipns1->k = KK;
   Q = m_get(kk,x->dim);
   Q1 = m_get(kk,x->dim);
   H = m_get(kk,kk);
   v_rand(u);
   ipns1->x = u;
   ipns1->shared_x = TRUE;
   mem_stat_mark(3);
   iter_arnoldi_iref(ipns1,&hh,Q,H);
   mem_stat_free(3);

   /* check the equality:
      Q*A*Q^T = H; */

   vt.dim = vt.max_dim = x->dim;
   vt1.dim = vt1.max_dim = x->dim;
   for (j=0; j < kk; j++) {
      vt.ve = Q->me[j];
      vt1.ve = Q1->me[j];
      sp_mv_mlt(An,&vt,&vt1);
   }
   H1 = m_get(kk,kk);
   mmtr_mlt(Q,Q1,H1);
   m_sub(H,H1,H1);
   if (m_norm_inf(H1) > MACHEPS*x->dim)
     printf(" (arnoldi_iref) ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n",
	    m_norm_inf(H1),MACHEPS);

   /* check Q*Q^T = I  */

   mmtr_mlt(Q,Q,H1);
   for (j=0; j < kk; j++)
     H1->me[j][j] -= 1.0;
   if (m_norm_inf(H1) > MACHEPS*x->dim)
     printf(" (arnoldi_iref) ||Q*Q^T - I|| = %g [cf. MACHEPS = %g]\n",
	    m_norm_inf(H1),MACHEPS);

   ipns1->x = u;
   ipns1->shared_x = TRUE;
   mem_stat_mark(3);
   iter_arnoldi(ipns1,&hh,Q,H);
   mem_stat_free(3);

   /* check the equality:
      Q*A*Q^T = H; */

   vt.dim = vt.max_dim = x->dim;
   vt1.dim = vt1.max_dim = x->dim;
   for (j=0; j < kk; j++) {
      vt.ve = Q->me[j];
      vt1.ve = Q1->me[j];
      sp_mv_mlt(An,&vt,&vt1);
   }

   mmtr_mlt(Q,Q1,H1);
   m_sub(H,H1,H1);
  if (m_norm_inf(H1) > MACHEPS*x->dim)  
     printf(" (arnoldi) ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n",
	    m_norm_inf(H1),MACHEPS);
   /* check Q*Q^T = I  */
   mmtr_mlt(Q,Q,H1);
   for (j=0; j < kk; j++)
     H1->me[j][j] -= 1.0;
   if (m_norm_inf(H1) > MACHEPS*x->dim)
     printf(" (arnoldi) ||Q*Q^T - I|| = %g [cf. MACHEPS = %g]\n",
	    m_norm_inf(H1),MACHEPS);

   v_rand(u);
   mem_stat_mark(3);
   iter_sparnoldi(An,u,kk,&hh,Q,H);
   mem_stat_free(3);

   /* check the equality:
      Q*A*Q^T = H; */

   vt.dim = vt.max_dim = x->dim;
   vt1.dim = vt1.max_dim = x->dim;
   for (j=0; j < kk; j++) {
      vt.ve = Q->me[j];
      vt1.ve = Q1->me[j];
      sp_mv_mlt(An,&vt,&vt1);
   }

   mmtr_mlt(Q,Q1,H1);
   m_sub(H,H1,H1);
   if (m_norm_inf(H1) > MACHEPS*x->dim)
     printf(" (sparnoldi) ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n",
	    m_norm_inf(H1),MACHEPS);
   /* check Q*Q^T = I  */
   mmtr_mlt(Q,Q,H1);
   for (j=0; j < kk; j++)
     H1->me[j][j] -= 1.0;
   if (m_norm_inf(H1) > MACHEPS*x->dim)
     printf(" (sparnoldi) ||Q*Q^T - I|| = %g [cf. MACHEPS = %g]\n",
	    m_norm_inf(H1),MACHEPS);



   /****** LANCZOS METHOD ******/

   notice("lanczos method");
   kk = ipns1->k; 
   Q = m_resize(Q,kk,x->dim);
   Q1 = m_resize(Q1,kk,x->dim);
   H = m_resize(H,kk,kk);
   ips1->k = kk;
   v_rand(u);
   v_free(ips1->x);
   ips1->x = u;
   ips1->shared_x = TRUE;

   mem_stat_mark(3);
   iter_lanczos(ips1,x,y,&hh,Q);
   mem_stat_free(3);

   /* check the equality:
      Q*A*Q^T = H; */

   vt.dim = vt1.dim = Q->n;
   vt.max_dim = vt1.max_dim = Q->max_n;
   Q1 = m_resize(Q1,Q->m,Q->n);
   for (j=0; j < Q->m; j++) {
      vt.ve = Q->me[j];
      vt1.ve = Q1->me[j];
      sp_mv_mlt(A,&vt,&vt1);
   }
   H1 = m_resize(H1,Q->m,Q->m);
   H = m_resize(H,Q->m,Q->m);
   mmtr_mlt(Q,Q1,H1);

   m_zero(H);
   for (j=0; j < Q->m-1; j++) {
      H->me[j][j] = x->ve[j];
      H->me[j][j+1] = H->me[j+1][j] = y->ve[j];
   }
   H->me[Q->m-1][Q->m-1] = x->ve[Q->m-1];

   m_sub(H,H1,H1);
   if (m_norm_inf(H1) > MACHEPS*x->dim)
     printf(" (lanczos) ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n",
	    m_norm_inf(H1),MACHEPS);

   /* check Q*Q^T = I  */

   mmtr_mlt(Q,Q,H1);
   for (j=0; j < Q->m; j++)
     H1->me[j][j] -= 1.0;
   if (m_norm_inf(H1) > MACHEPS*x->dim)
     printf(" (lanczos) ||Q*Q^T - I|| = %g [cf. MACHEPS = %g]\n",
	    m_norm_inf(H1),MACHEPS);

   mem_stat_mark(3);
   v_rand(u);
   iter_splanczos(A,kk,u,x,y,&hh,Q);
   mem_stat_free(3);

   /* check the equality:
      Q*A*Q^T = H; */

   vt.dim = vt1.dim = Q->n;
   vt.max_dim = vt1.max_dim = Q->max_n;
   Q1 = m_resize(Q1,Q->m,Q->n);
   for (j=0; j < Q->m; j++) {
      vt.ve = Q->me[j];
      vt1.ve = Q1->me[j];
      sp_mv_mlt(A,&vt,&vt1);
   }
   H1 = m_resize(H1,Q->m,Q->m);
   H = m_resize(H,Q->m,Q->m);
   mmtr_mlt(Q,Q1,H1);
   for (j=0; j < Q->m-1; j++) {
      H->me[j][j] = x->ve[j];
      H->me[j][j+1] = H->me[j+1][j] = y->ve[j];
   }
   H->me[Q->m-1][Q->m-1] = x->ve[Q->m-1];

   m_sub(H,H1,H1);
   if (m_norm_inf(H1) > MACHEPS*x->dim)
     printf(" (splanczos) ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n",
	    m_norm_inf(H1),MACHEPS);
   /* check Q*Q^T = I  */
   mmtr_mlt(Q,Q,H1);
   for (j=0; j < Q->m; j++)
     H1->me[j][j] -= 1.0;
   if (m_norm_inf(H1) > MACHEPS*x->dim)
     printf(" (splanczos) ||Q*Q^T - I|| = %g [cf. MACHEPS = %g]\n",
	    m_norm_inf(H1),MACHEPS);



   /***** LANCZOS2 ****/

   notice("lanczos2 method");
   kk = 50;  		/* # of dir. vectors */
   ips1->k = kk;
   v_rand(u);
   ips1->x = u;
   ips1->shared_x = TRUE;

   for ( i = 0; i < xn->dim; i++ )
	xn->ve[i] = i;
   iter_Ax(ips1,Dv_mlt,xn);
   mem_stat_mark(3);
   iter_lanczos2(ips1,y,v);
   mem_stat_free(3);

   printf("# Number of steps of Lanczos algorithm = %d\n", kk);
   printf("# Exact eigenvalues are 0, 1, 2, ..., %d\n",ANON-1);
   printf("# Extreme eigenvalues should be accurate; \n");
   printf("# interior values usually are not.\n");
   printf("# approx e-vals =\n");	v_output(y);
   printf("# Error in estimate of bottom e-vec (Lanczos) = %g\n",
	  fabs(v->ve[0]));

   mem_stat_mark(3);
   v_rand(u);
   iter_splanczos2(A,kk,u,y,v);
   mem_stat_free(3);


   /***** FINISHING *******/

   notice("release ITER variables");
   
   M_FREE(Q);
   M_FREE(Q1);
   M_FREE(H);
   M_FREE(H1);

   ITER_FREE(ipns);
   ITER_FREE(ips);
   ITER_FREE(ipns1);
   ITER_FREE(ips1);
   SP_FREE(A);
   SP_FREE(B);
   SP_FREE(An);
   SP_FREE(Bn);
   
   V_FREE(x);
   V_FREE(y);
   V_FREE(u);
   V_FREE(v); 
   V_FREE(xn);
   V_FREE(yn);

   printf("# Done testing (%s)\n",argv[0]);
   mem_info();
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?