1*c4762a1bSJed Brown /* XH: 2*c4762a1bSJed Brown Todo: add cs1f.F90 and adjust makefile. 3*c4762a1bSJed Brown Todo: maybe provide code template to generate 1D/2D/3D gradient, DCT transform matrix for D etc. 4*c4762a1bSJed Brown */ 5*c4762a1bSJed Brown /* 6*c4762a1bSJed Brown Include "petsctao.h" so that we can use TAO solvers. Note that this 7*c4762a1bSJed Brown file automatically includes libraries such as: 8*c4762a1bSJed Brown petsc.h - base PETSc routines petscvec.h - vectors 9*c4762a1bSJed Brown petscsys.h - sysem routines petscmat.h - matrices 10*c4762a1bSJed Brown petscis.h - index sets petscksp.h - Krylov subspace methods 11*c4762a1bSJed Brown petscviewer.h - viewers petscpc.h - preconditioners 12*c4762a1bSJed Brown 13*c4762a1bSJed Brown */ 14*c4762a1bSJed Brown 15*c4762a1bSJed Brown #include <petsctao.h> 16*c4762a1bSJed Brown 17*c4762a1bSJed Brown /* 18*c4762a1bSJed Brown Description: BRGN tomography reconstruction example . 19*c4762a1bSJed Brown 0.5*||Ax-b||^2 + lambda*g(x) 20*c4762a1bSJed Brown Reference: None 21*c4762a1bSJed Brown */ 22*c4762a1bSJed Brown 23*c4762a1bSJed Brown static char help[] = "Finds the least-squares solution to the under constraint linear model Ax = b, with regularizer. \n\ 24*c4762a1bSJed Brown A is a M*N real matrix (M<N), x is sparse. A good regularizer is an L1 regularizer. \n\ 25*c4762a1bSJed Brown We find the sparse solution by solving 0.5*||Ax-b||^2 + lambda*||D*x||_1, where lambda (by default 1e-4) is a user specified weight.\n\ 26*c4762a1bSJed Brown D is the K*N transform matrix so that D*x is sparse. By default D is identity matrix, so that D*x = x.\n"; 27*c4762a1bSJed Brown /*T 28*c4762a1bSJed Brown Concepts: TAO^Solving a system of nonlinear equations, nonlinear least squares 29*c4762a1bSJed Brown Routines: TaoCreate(); 30*c4762a1bSJed Brown Routines: TaoSetType(); 31*c4762a1bSJed Brown Routines: TaoSetSeparableObjectiveRoutine(); 32*c4762a1bSJed Brown Routines: TaoSetJacobianRoutine(); 33*c4762a1bSJed Brown Routines: TaoSetInitialVector(); 34*c4762a1bSJed Brown Routines: TaoSetFromOptions(); 35*c4762a1bSJed Brown Routines: TaoSetConvergenceHistory(); TaoGetConvergenceHistory(); 36*c4762a1bSJed Brown Routines: TaoSolve(); 37*c4762a1bSJed Brown Routines: TaoView(); TaoDestroy(); 38*c4762a1bSJed Brown Processors: 1 39*c4762a1bSJed Brown T*/ 40*c4762a1bSJed Brown 41*c4762a1bSJed Brown /* User-defined application context */ 42*c4762a1bSJed Brown typedef struct { 43*c4762a1bSJed Brown /* Working space. linear least square: res(x) = A*x - b */ 44*c4762a1bSJed Brown PetscInt M,N,K; /* Problem dimension: A is M*N Matrix, D is K*N Matrix */ 45*c4762a1bSJed Brown Mat A,D; /* Coefficients, Dictionary Transform of size M*N and K*N respectively. For linear least square, Jacobian Matrix J = A. For nonlinear least square, it is different from A */ 46*c4762a1bSJed Brown Vec b,xGT,xlb,xub; /* observation b, ground truth xGT, the lower bound and upper bound of x*/ 47*c4762a1bSJed Brown } AppCtx; 48*c4762a1bSJed Brown 49*c4762a1bSJed Brown /* User provided Routines */ 50*c4762a1bSJed Brown PetscErrorCode InitializeUserData(AppCtx *); 51*c4762a1bSJed Brown PetscErrorCode FormStartingPoint(Vec,AppCtx *); 52*c4762a1bSJed Brown PetscErrorCode EvaluateResidual(Tao,Vec,Vec,void *); 53*c4762a1bSJed Brown PetscErrorCode EvaluateJacobian(Tao,Vec,Mat,Mat,void *); 54*c4762a1bSJed Brown PetscErrorCode EvaluateRegularizerObjectiveAndGradient(Tao,Vec,PetscReal *,Vec,void*); 55*c4762a1bSJed Brown PetscErrorCode EvaluateRegularizerHessian(Tao,Vec,Mat,void*); 56*c4762a1bSJed Brown PetscErrorCode EvaluateRegularizerHessianProd(Mat,Vec,Vec); 57*c4762a1bSJed Brown 58*c4762a1bSJed Brown /*--------------------------------------------------------------------*/ 59*c4762a1bSJed Brown int main(int argc,char **argv) 60*c4762a1bSJed Brown { 61*c4762a1bSJed Brown PetscErrorCode ierr; /* used to check for functions returning nonzeros */ 62*c4762a1bSJed Brown Vec x,res; /* solution, function res(x) = A*x-b */ 63*c4762a1bSJed Brown Mat Hreg; /* regularizer Hessian matrix for user specified regularizer*/ 64*c4762a1bSJed Brown Tao tao; /* Tao solver context */ 65*c4762a1bSJed Brown PetscReal hist[100],resid[100],v1,v2; 66*c4762a1bSJed Brown PetscInt lits[100]; 67*c4762a1bSJed Brown AppCtx user; /* user-defined work context */ 68*c4762a1bSJed Brown PetscViewer fd; /* used to save result to file */ 69*c4762a1bSJed Brown char resultFile[] = "tomographyResult_x"; /* Debug: change from "tomographyResult_x" to "cs1Result_x" */ 70*c4762a1bSJed Brown 71*c4762a1bSJed Brown ierr = PetscInitialize(&argc,&argv,(char *)0,help);if (ierr) return ierr; 72*c4762a1bSJed Brown 73*c4762a1bSJed Brown /* Create TAO solver and set desired solution method */ 74*c4762a1bSJed Brown ierr = TaoCreate(PETSC_COMM_SELF,&tao);CHKERRQ(ierr); 75*c4762a1bSJed Brown ierr = TaoSetType(tao,TAOBRGN);CHKERRQ(ierr); 76*c4762a1bSJed Brown 77*c4762a1bSJed Brown /* User set application context: A, D matrice, and b vector. */ 78*c4762a1bSJed Brown ierr = InitializeUserData(&user);CHKERRQ(ierr); 79*c4762a1bSJed Brown 80*c4762a1bSJed Brown /* Allocate solution vector x, and function vectors Ax-b, */ 81*c4762a1bSJed Brown ierr = VecCreateSeq(PETSC_COMM_SELF,user.N,&x);CHKERRQ(ierr); 82*c4762a1bSJed Brown ierr = VecCreateSeq(PETSC_COMM_SELF,user.M,&res);CHKERRQ(ierr); 83*c4762a1bSJed Brown 84*c4762a1bSJed Brown /* Set initial guess */ 85*c4762a1bSJed Brown ierr = FormStartingPoint(x,&user);CHKERRQ(ierr); 86*c4762a1bSJed Brown 87*c4762a1bSJed Brown /* Bind x to tao->solution. */ 88*c4762a1bSJed Brown ierr = TaoSetInitialVector(tao,x);CHKERRQ(ierr); 89*c4762a1bSJed Brown /* Sets the upper and lower bounds of x */ 90*c4762a1bSJed Brown ierr = TaoSetVariableBounds(tao,user.xlb,user.xub);CHKERRQ(ierr); 91*c4762a1bSJed Brown 92*c4762a1bSJed Brown /* Bind user.D to tao->data->D */ 93*c4762a1bSJed Brown ierr = TaoBRGNSetDictionaryMatrix(tao,user.D);CHKERRQ(ierr); 94*c4762a1bSJed Brown 95*c4762a1bSJed Brown /* Set the residual function and Jacobian routines for least squares. */ 96*c4762a1bSJed Brown ierr = TaoSetResidualRoutine(tao,res,EvaluateResidual,(void*)&user);CHKERRQ(ierr); 97*c4762a1bSJed Brown /* Jacobian matrix fixed as user.A for Linear least sqaure problem. */ 98*c4762a1bSJed Brown ierr = TaoSetJacobianResidualRoutine(tao,user.A,user.A,EvaluateJacobian,(void*)&user);CHKERRQ(ierr); 99*c4762a1bSJed Brown 100*c4762a1bSJed Brown /* User set the regularizer objective, gradient, and hessian. Set it the same as using l2prox choice, for testing purpose. */ 101*c4762a1bSJed Brown ierr = TaoBRGNSetRegularizerObjectiveAndGradientRoutine(tao,EvaluateRegularizerObjectiveAndGradient,(void*)&user);CHKERRQ(ierr); 102*c4762a1bSJed Brown /* User defined regularizer Hessian setup, here is identiy shell matrix */ 103*c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_SELF,&Hreg);CHKERRQ(ierr); 104*c4762a1bSJed Brown ierr = MatSetSizes(Hreg,PETSC_DECIDE,PETSC_DECIDE,user.N,user.N);CHKERRQ(ierr); 105*c4762a1bSJed Brown ierr = MatSetType(Hreg,MATSHELL);CHKERRQ(ierr); 106*c4762a1bSJed Brown ierr = MatSetUp(Hreg);CHKERRQ(ierr); 107*c4762a1bSJed Brown ierr = MatShellSetOperation(Hreg,MATOP_MULT,(void (*)(void))EvaluateRegularizerHessianProd);CHKERRQ(ierr); 108*c4762a1bSJed Brown ierr = TaoBRGNSetRegularizerHessianRoutine(tao,Hreg,EvaluateRegularizerHessian,(void*)&user);CHKERRQ(ierr); 109*c4762a1bSJed Brown 110*c4762a1bSJed Brown /* Check for any TAO command line arguments */ 111*c4762a1bSJed Brown ierr = TaoSetFromOptions(tao);CHKERRQ(ierr); 112*c4762a1bSJed Brown 113*c4762a1bSJed Brown ierr = TaoSetConvergenceHistory(tao,hist,resid,0,lits,100,PETSC_TRUE);CHKERRQ(ierr); 114*c4762a1bSJed Brown 115*c4762a1bSJed Brown /* Perform the Solve */ 116*c4762a1bSJed Brown ierr = TaoSolve(tao);CHKERRQ(ierr); 117*c4762a1bSJed Brown 118*c4762a1bSJed Brown /* Save x (reconstruction of object) vector to a binary file, which maybe read from Matlab and convert to a 2D image for comparison. */ 119*c4762a1bSJed Brown ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,resultFile,FILE_MODE_WRITE,&fd);CHKERRQ(ierr); 120*c4762a1bSJed Brown ierr = VecView(x,fd);CHKERRQ(ierr); 121*c4762a1bSJed Brown ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); 122*c4762a1bSJed Brown 123*c4762a1bSJed Brown /* compute the error */ 124*c4762a1bSJed Brown ierr = VecAXPY(x,-1,user.xGT);CHKERRQ(ierr); 125*c4762a1bSJed Brown ierr = VecNorm(x,NORM_2,&v1);CHKERRQ(ierr); 126*c4762a1bSJed Brown ierr = VecNorm(user.xGT,NORM_2,&v2);CHKERRQ(ierr); 127*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "relative reconstruction error: ||x-xGT||/||xGT|| = %6.4e.\n", (double)(v1/v2));CHKERRQ(ierr); 128*c4762a1bSJed Brown 129*c4762a1bSJed Brown /* Free TAO data structures */ 130*c4762a1bSJed Brown ierr = TaoDestroy(&tao);CHKERRQ(ierr); 131*c4762a1bSJed Brown 132*c4762a1bSJed Brown /* Free PETSc data structures */ 133*c4762a1bSJed Brown ierr = VecDestroy(&x);CHKERRQ(ierr); 134*c4762a1bSJed Brown ierr = VecDestroy(&res);CHKERRQ(ierr); 135*c4762a1bSJed Brown ierr = MatDestroy(&Hreg);CHKERRQ(ierr); 136*c4762a1bSJed Brown /* Free user data structures */ 137*c4762a1bSJed Brown ierr = MatDestroy(&user.A);CHKERRQ(ierr); 138*c4762a1bSJed Brown ierr = MatDestroy(&user.D);CHKERRQ(ierr); 139*c4762a1bSJed Brown ierr = VecDestroy(&user.b);CHKERRQ(ierr); 140*c4762a1bSJed Brown ierr = VecDestroy(&user.xGT);CHKERRQ(ierr); 141*c4762a1bSJed Brown ierr = VecDestroy(&user.xlb);CHKERRQ(ierr); 142*c4762a1bSJed Brown ierr = VecDestroy(&user.xub);CHKERRQ(ierr); 143*c4762a1bSJed Brown ierr = PetscFinalize(); 144*c4762a1bSJed Brown return ierr; 145*c4762a1bSJed Brown } 146*c4762a1bSJed Brown 147*c4762a1bSJed Brown /*--------------------------------------------------------------------*/ 148*c4762a1bSJed Brown /* Evaluate residual function A(x)-b in least square problem ||A(x)-b||^2 */ 149*c4762a1bSJed Brown PetscErrorCode EvaluateResidual(Tao tao,Vec X,Vec F,void *ptr) 150*c4762a1bSJed Brown { 151*c4762a1bSJed Brown AppCtx *user = (AppCtx *)ptr; 152*c4762a1bSJed Brown PetscErrorCode ierr; 153*c4762a1bSJed Brown 154*c4762a1bSJed Brown PetscFunctionBegin; 155*c4762a1bSJed Brown /* Compute Ax - b */ 156*c4762a1bSJed Brown ierr = MatMult(user->A,X,F);CHKERRQ(ierr); 157*c4762a1bSJed Brown ierr = VecAXPY(F,-1,user->b);CHKERRQ(ierr); 158*c4762a1bSJed Brown PetscLogFlops(user->M*user->N*2); 159*c4762a1bSJed Brown PetscFunctionReturn(0); 160*c4762a1bSJed Brown } 161*c4762a1bSJed Brown 162*c4762a1bSJed Brown /*------------------------------------------------------------*/ 163*c4762a1bSJed Brown PetscErrorCode EvaluateJacobian(Tao tao,Vec X,Mat J,Mat Jpre,void *ptr) 164*c4762a1bSJed Brown { 165*c4762a1bSJed Brown /* Jacobian is not changing here, so use a empty dummy function here. J[m][n] = df[m]/dx[n] = A[m][n] for linear least square */ 166*c4762a1bSJed Brown PetscFunctionBegin; 167*c4762a1bSJed Brown PetscFunctionReturn(0); 168*c4762a1bSJed Brown } 169*c4762a1bSJed Brown 170*c4762a1bSJed Brown /* ------------------------------------------------------------ */ 171*c4762a1bSJed Brown PetscErrorCode EvaluateRegularizerObjectiveAndGradient(Tao tao,Vec X,PetscReal *f_reg,Vec G_reg,void *ptr) 172*c4762a1bSJed Brown { 173*c4762a1bSJed Brown PetscErrorCode ierr; 174*c4762a1bSJed Brown 175*c4762a1bSJed Brown PetscFunctionBegin; 176*c4762a1bSJed Brown /* compute regularizer objective = 0.5*x'*x */ 177*c4762a1bSJed Brown ierr = VecDot(X,X,f_reg);CHKERRQ(ierr); 178*c4762a1bSJed Brown *f_reg *= 0.5; 179*c4762a1bSJed Brown /* compute regularizer gradient = x */ 180*c4762a1bSJed Brown ierr = VecCopy(X,G_reg);CHKERRQ(ierr); 181*c4762a1bSJed Brown PetscFunctionReturn(0); 182*c4762a1bSJed Brown } 183*c4762a1bSJed Brown 184*c4762a1bSJed Brown PetscErrorCode EvaluateRegularizerHessianProd(Mat Hreg,Vec in,Vec out) 185*c4762a1bSJed Brown { 186*c4762a1bSJed Brown PetscErrorCode ierr; 187*c4762a1bSJed Brown PetscFunctionBegin; 188*c4762a1bSJed Brown ierr = VecCopy(in,out);CHKERRQ(ierr); 189*c4762a1bSJed Brown PetscFunctionReturn(0); 190*c4762a1bSJed Brown } 191*c4762a1bSJed Brown 192*c4762a1bSJed Brown /* ------------------------------------------------------------ */ 193*c4762a1bSJed Brown PetscErrorCode EvaluateRegularizerHessian(Tao tao,Vec X,Mat Hreg,void *ptr) 194*c4762a1bSJed Brown { 195*c4762a1bSJed Brown /* Hessian for regularizer objective = 0.5*x'*x is identity matrix, and is not changing*/ 196*c4762a1bSJed Brown PetscFunctionBegin; 197*c4762a1bSJed Brown PetscFunctionReturn(0); 198*c4762a1bSJed Brown } 199*c4762a1bSJed Brown 200*c4762a1bSJed Brown /* ------------------------------------------------------------ */ 201*c4762a1bSJed Brown PetscErrorCode FormStartingPoint(Vec X,AppCtx *user) 202*c4762a1bSJed Brown { 203*c4762a1bSJed Brown PetscErrorCode ierr; 204*c4762a1bSJed Brown PetscFunctionBegin; 205*c4762a1bSJed Brown ierr = VecSet(X,0.0);CHKERRQ(ierr); 206*c4762a1bSJed Brown PetscFunctionReturn(0); 207*c4762a1bSJed Brown } 208*c4762a1bSJed Brown 209*c4762a1bSJed Brown /* ---------------------------------------------------------------------- */ 210*c4762a1bSJed Brown PetscErrorCode InitializeUserData(AppCtx *user) 211*c4762a1bSJed Brown { 212*c4762a1bSJed Brown PetscInt k,n; /* indices for row and columns of D. */ 213*c4762a1bSJed Brown char dataFile[] = "tomographyData_A_b_xGT"; /* Matrix A and vectors b, xGT(ground truth) binary files generated by Matlab. Debug: change from "tomographyData_A_b_xGT" to "cs1Data_A_b_xGT". */ 214*c4762a1bSJed Brown PetscInt dictChoice = 1; /* choose from 0:identity, 1:gradient1D, 2:gradient2D, 3:DCT etc */ 215*c4762a1bSJed Brown PetscViewer fd; /* used to load data from file */ 216*c4762a1bSJed Brown PetscErrorCode ierr; 217*c4762a1bSJed Brown PetscReal v; 218*c4762a1bSJed Brown 219*c4762a1bSJed Brown PetscFunctionBegin; 220*c4762a1bSJed Brown 221*c4762a1bSJed Brown /* 222*c4762a1bSJed Brown Matrix Vector read and write refer to: 223*c4762a1bSJed Brown https://www.mcs.anl.gov/petsc/petsc-current/src/mat/tutorials/ex10.c 224*c4762a1bSJed Brown https://www.mcs.anl.gov/petsc/petsc-current/src/mat/tutorials/ex12.c 225*c4762a1bSJed Brown */ 226*c4762a1bSJed Brown /* Load the A matrix, b vector, and xGT vector from a binary file. */ 227*c4762a1bSJed Brown ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,dataFile,FILE_MODE_READ,&fd);CHKERRQ(ierr); 228*c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD,&user->A);CHKERRQ(ierr); 229*c4762a1bSJed Brown ierr = MatSetType(user->A,MATSEQAIJ);CHKERRQ(ierr); 230*c4762a1bSJed Brown ierr = MatLoad(user->A,fd);CHKERRQ(ierr); 231*c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&user->b);CHKERRQ(ierr); 232*c4762a1bSJed Brown ierr = VecLoad(user->b,fd);CHKERRQ(ierr); 233*c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&user->xGT);CHKERRQ(ierr); 234*c4762a1bSJed Brown ierr = VecLoad(user->xGT,fd);CHKERRQ(ierr); 235*c4762a1bSJed Brown ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); 236*c4762a1bSJed Brown ierr = VecDuplicate(user->xGT,&(user->xlb));CHKERRQ(ierr); 237*c4762a1bSJed Brown ierr = VecSet(user->xlb,0.0);CHKERRQ(ierr); 238*c4762a1bSJed Brown ierr = VecDuplicate(user->xGT,&(user->xub));CHKERRQ(ierr); 239*c4762a1bSJed Brown ierr = VecSet(user->xub,PETSC_INFINITY);CHKERRQ(ierr); 240*c4762a1bSJed Brown 241*c4762a1bSJed Brown /* Specify the size */ 242*c4762a1bSJed Brown ierr = MatGetSize(user->A,&user->M,&user->N);CHKERRQ(ierr); 243*c4762a1bSJed Brown 244*c4762a1bSJed Brown /* shortcut, when D is identity matrix, we may just specify it as NULL, and brgn will treat D*x as x without actually computing D*x. 245*c4762a1bSJed Brown if (dictChoice == 0) { 246*c4762a1bSJed Brown user->D = NULL; 247*c4762a1bSJed Brown PetscFunctionReturn(0); 248*c4762a1bSJed Brown } 249*c4762a1bSJed Brown */ 250*c4762a1bSJed Brown 251*c4762a1bSJed Brown /* Speficy D */ 252*c4762a1bSJed Brown /* (1) Specify D Size */ 253*c4762a1bSJed Brown switch (dictChoice) { 254*c4762a1bSJed Brown case 0: /* 0:identity */ 255*c4762a1bSJed Brown user->K = user->N; 256*c4762a1bSJed Brown break; 257*c4762a1bSJed Brown case 1: /* 1:gradient1D */ 258*c4762a1bSJed Brown user->K = user->N-1; 259*c4762a1bSJed Brown break; 260*c4762a1bSJed Brown } 261*c4762a1bSJed Brown 262*c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_SELF,&user->D);CHKERRQ(ierr); 263*c4762a1bSJed Brown ierr = MatSetSizes(user->D,PETSC_DECIDE,PETSC_DECIDE,user->K,user->N);CHKERRQ(ierr); 264*c4762a1bSJed Brown ierr = MatSetFromOptions(user->D);CHKERRQ(ierr); 265*c4762a1bSJed Brown ierr = MatSetUp(user->D);CHKERRQ(ierr); 266*c4762a1bSJed Brown 267*c4762a1bSJed Brown /* (2) Specify D Content */ 268*c4762a1bSJed Brown switch (dictChoice) { 269*c4762a1bSJed Brown case 0: /* 0:identity */ 270*c4762a1bSJed Brown for (k=0; k<user->K; k++) { 271*c4762a1bSJed Brown v = 1.0; 272*c4762a1bSJed Brown ierr = MatSetValues(user->D,1,&k,1,&k,&v,INSERT_VALUES);CHKERRQ(ierr); 273*c4762a1bSJed Brown } 274*c4762a1bSJed Brown break; 275*c4762a1bSJed Brown case 1: /* 1:gradient1D. [-1, 1, 0,...; 0, -1, 1, 0, ...] */ 276*c4762a1bSJed Brown for (k=0; k<user->K; k++) { 277*c4762a1bSJed Brown v = 1.0; 278*c4762a1bSJed Brown n = k+1; 279*c4762a1bSJed Brown ierr = MatSetValues(user->D,1,&k,1,&n,&v,INSERT_VALUES);CHKERRQ(ierr); 280*c4762a1bSJed Brown v = -1.0; 281*c4762a1bSJed Brown ierr = MatSetValues(user->D,1,&k,1,&k,&v,INSERT_VALUES);CHKERRQ(ierr); 282*c4762a1bSJed Brown } 283*c4762a1bSJed Brown break; 284*c4762a1bSJed Brown } 285*c4762a1bSJed Brown ierr = MatAssemblyBegin(user->D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 286*c4762a1bSJed Brown ierr = MatAssemblyEnd(user->D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 287*c4762a1bSJed Brown 288*c4762a1bSJed Brown PetscFunctionReturn(0); 289*c4762a1bSJed Brown } 290*c4762a1bSJed Brown 291*c4762a1bSJed Brown /*TEST 292*c4762a1bSJed Brown 293*c4762a1bSJed Brown build: 294*c4762a1bSJed Brown requires: !complex !single !__float128 !define(PETSC_USE_64BIT_INDICES) 295*c4762a1bSJed Brown 296*c4762a1bSJed Brown test: 297*c4762a1bSJed Brown localrunfiles: tomographyData_A_b_xGT 298*c4762a1bSJed Brown args: -tao_max_it 1000 -tao_brgn_regularization_type l1dict -tao_brgn_regularizer_weight 1e-8 -tao_brgn_l1_smooth_epsilon 1e-6 -tao_gatol 1.e-8 299*c4762a1bSJed Brown 300*c4762a1bSJed Brown test: 301*c4762a1bSJed Brown suffix: 2 302*c4762a1bSJed Brown localrunfiles: tomographyData_A_b_xGT 303*c4762a1bSJed Brown args: -tao_monitor -tao_max_it 1000 -tao_brgn_regularization_type l2prox -tao_brgn_regularizer_weight 1e-8 -tao_gatol 1.e-6 304*c4762a1bSJed Brown 305*c4762a1bSJed Brown test: 306*c4762a1bSJed Brown suffix: 3 307*c4762a1bSJed Brown localrunfiles: tomographyData_A_b_xGT 308*c4762a1bSJed Brown args: -tao_monitor -tao_max_it 1000 -tao_brgn_regularization_type user -tao_brgn_regularizer_weight 1e-8 -tao_gatol 1.e-6 309*c4762a1bSJed Brown 310*c4762a1bSJed Brown TEST*/ 311