xref: /petsc/src/tao/interface/fdiff.c (revision a7e14dcfba0d07adf6226a919460249440ec94c7)
1*a7e14dcfSSatish Balay #include "taosolver.h"         /*I  "taosolver.h"  I*/
2*a7e14dcfSSatish Balay #include "tao-private/taosolver_impl.h"
3*a7e14dcfSSatish Balay #include "petscsnes.h"
4*a7e14dcfSSatish Balay 
5*a7e14dcfSSatish Balay 
6*a7e14dcfSSatish Balay /*
7*a7e14dcfSSatish Balay    For finited difference computations of the Hessian, we use PETSc's SNESComputeJacobianDefault
8*a7e14dcfSSatish Balay */
9*a7e14dcfSSatish Balay 
10*a7e14dcfSSatish Balay #undef __FUNCT__
11*a7e14dcfSSatish Balay #define __FUNCT__ "Fsnes"
12*a7e14dcfSSatish Balay static PetscErrorCode Fsnes(SNES snes ,Vec X,Vec G,void*ctx){
13*a7e14dcfSSatish Balay   PetscErrorCode ierr;
14*a7e14dcfSSatish Balay   TaoSolver tao = (TaoSolver)ctx;
15*a7e14dcfSSatish Balay   PetscFunctionBegin;
16*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(ctx,TAOSOLVER_CLASSID,4);
17*a7e14dcfSSatish Balay   ierr=TaoComputeGradient(tao,X,G); CHKERRQ(ierr);
18*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
19*a7e14dcfSSatish Balay }
20*a7e14dcfSSatish Balay 
21*a7e14dcfSSatish Balay #undef __FUNCT__
22*a7e14dcfSSatish Balay #define __FUNCT__ "TaoDefaultComputeGradient"
23*a7e14dcfSSatish Balay /*@C
24*a7e14dcfSSatish Balay   TaoDefaultComputeGradient - computes the gradient using finite differences.
25*a7e14dcfSSatish Balay 
26*a7e14dcfSSatish Balay   Collective on TaoSolver
27*a7e14dcfSSatish Balay 
28*a7e14dcfSSatish Balay   Input Parameters:
29*a7e14dcfSSatish Balay + tao - the TaoSolver context
30*a7e14dcfSSatish Balay . X - compute gradient at this point
31*a7e14dcfSSatish Balay - dummy - not used
32*a7e14dcfSSatish Balay 
33*a7e14dcfSSatish Balay   Output Parameters:
34*a7e14dcfSSatish Balay . G - Gradient Vector
35*a7e14dcfSSatish Balay 
36*a7e14dcfSSatish Balay    Options Database Key:
37*a7e14dcfSSatish Balay +  -tao_fd_gradient - Activates TaoDefaultComputeGradient()
38*a7e14dcfSSatish Balay -  -tao_fd_delta <delta> - change in x used to calculate finite differences
39*a7e14dcfSSatish Balay 
40*a7e14dcfSSatish Balay 
41*a7e14dcfSSatish Balay 
42*a7e14dcfSSatish Balay 
43*a7e14dcfSSatish Balay    Level: advanced
44*a7e14dcfSSatish Balay 
45*a7e14dcfSSatish Balay    Note:
46*a7e14dcfSSatish Balay    This routine is slow and expensive, and is not currently optimized
47*a7e14dcfSSatish Balay    to take advantage of sparsity in the problem.  Although
48*a7e14dcfSSatish Balay    TaoAppDefaultComputeGradient is not recommended for general use
49*a7e14dcfSSatish Balay    in large-scale applications, It can be useful in checking the
50*a7e14dcfSSatish Balay    correctness of a user-provided gradient.  Use the tao method "tao_fd_test"
51*a7e14dcfSSatish Balay    to get an indication of whether your gradient is correct.
52*a7e14dcfSSatish Balay 
53*a7e14dcfSSatish Balay 
54*a7e14dcfSSatish Balay    Note:
55*a7e14dcfSSatish Balay    This finite difference gradient evaluation can be set using the routine TaoSetGradientRoutine() or by using the command line option -tao_fd_gradient
56*a7e14dcfSSatish Balay 
57*a7e14dcfSSatish Balay .seealso: TaoSetGradientRoutine()
58*a7e14dcfSSatish Balay 
59*a7e14dcfSSatish Balay @*/
60*a7e14dcfSSatish Balay PetscErrorCode TaoDefaultComputeGradient(TaoSolver tao,Vec X,Vec G,void *dummy)
61*a7e14dcfSSatish Balay {
62*a7e14dcfSSatish Balay   PetscReal *g;
63*a7e14dcfSSatish Balay   PetscReal f, f2;
64*a7e14dcfSSatish Balay   PetscErrorCode ierr;
65*a7e14dcfSSatish Balay   PetscInt low,high,N,i;
66*a7e14dcfSSatish Balay   PetscBool flg;
67*a7e14dcfSSatish Balay   PetscReal h=PETSC_SQRT_MACHINE_EPSILON;
68*a7e14dcfSSatish Balay   PetscFunctionBegin;
69*a7e14dcfSSatish Balay   ierr = TaoComputeObjective(tao, X,&f); CHKERRQ(ierr);
70*a7e14dcfSSatish Balay   ierr = PetscOptionsGetReal(PETSC_NULL,"-tao_fd_delta",&h,&flg); CHKERRQ(ierr);
71*a7e14dcfSSatish Balay   ierr = VecGetSize(X,&N); CHKERRQ(ierr);
72*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(X,&low,&high); CHKERRQ(ierr);
73*a7e14dcfSSatish Balay   ierr = VecGetArray(G,&g); CHKERRQ(ierr);
74*a7e14dcfSSatish Balay   for (i=0;i<N;i++) {
75*a7e14dcfSSatish Balay       ierr = VecSetValue(X,i,h,ADD_VALUES); CHKERRQ(ierr);
76*a7e14dcfSSatish Balay       ierr = VecAssemblyBegin(X); CHKERRQ(ierr);
77*a7e14dcfSSatish Balay       ierr = VecAssemblyEnd(X); CHKERRQ(ierr);
78*a7e14dcfSSatish Balay 
79*a7e14dcfSSatish Balay       ierr = TaoComputeObjective(tao,X,&f2); CHKERRQ(ierr);
80*a7e14dcfSSatish Balay 
81*a7e14dcfSSatish Balay       ierr = VecSetValue(X,i,-h,ADD_VALUES);
82*a7e14dcfSSatish Balay       ierr = VecAssemblyBegin(X); CHKERRQ(ierr);
83*a7e14dcfSSatish Balay       ierr = VecAssemblyEnd(X); CHKERRQ(ierr);
84*a7e14dcfSSatish Balay 
85*a7e14dcfSSatish Balay       if (i>=low && i<high) {
86*a7e14dcfSSatish Balay 	  g[i-low]=(f2-f)/h;
87*a7e14dcfSSatish Balay       }
88*a7e14dcfSSatish Balay   }
89*a7e14dcfSSatish Balay   ierr = VecRestoreArray(G,&g); CHKERRQ(ierr);
90*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
91*a7e14dcfSSatish Balay }
92*a7e14dcfSSatish Balay 
93*a7e14dcfSSatish Balay #undef __FUNCT__
94*a7e14dcfSSatish Balay #define __FUNCT__ "TaoDefaultComputeHessian"
95*a7e14dcfSSatish Balay /*@C
96*a7e14dcfSSatish Balay    TaoDefaultComputeHessian - Computes the Hessian using finite differences.
97*a7e14dcfSSatish Balay 
98*a7e14dcfSSatish Balay    Collective on TaoSolver
99*a7e14dcfSSatish Balay 
100*a7e14dcfSSatish Balay    Input Parameters:
101*a7e14dcfSSatish Balay +  tao - the TaoSolver context
102*a7e14dcfSSatish Balay .  V - compute Hessian at this point
103*a7e14dcfSSatish Balay -  dummy - not used
104*a7e14dcfSSatish Balay 
105*a7e14dcfSSatish Balay    Output Parameters:
106*a7e14dcfSSatish Balay +  H - Hessian matrix (not altered in this routine)
107*a7e14dcfSSatish Balay .  B - newly computed Hessian matrix to use with preconditioner (generally the same as H)
108*a7e14dcfSSatish Balay -  flag - flag indicating whether the matrix sparsity structure has changed
109*a7e14dcfSSatish Balay 
110*a7e14dcfSSatish Balay    Options Database Key:
111*a7e14dcfSSatish Balay +  -tao_fd - Activates TaoDefaultComputeHessian()
112*a7e14dcfSSatish Balay -  -tao_view_hessian - view the hessian after each evaluation using PETSC_VIEWER_STDOUT_WORLD
113*a7e14dcfSSatish Balay 
114*a7e14dcfSSatish Balay    Level: advanced
115*a7e14dcfSSatish Balay 
116*a7e14dcfSSatish Balay    Notes:
117*a7e14dcfSSatish Balay    This routine is slow and expensive, and is not currently optimized
118*a7e14dcfSSatish Balay    to take advantage of sparsity in the problem.  Although
119*a7e14dcfSSatish Balay    TaoDefaultComputeHessian() is not recommended for general use
120*a7e14dcfSSatish Balay    in large-scale applications, It can be useful in checking the
121*a7e14dcfSSatish Balay    correctness of a user-provided Hessian.
122*a7e14dcfSSatish Balay 
123*a7e14dcfSSatish Balay 
124*a7e14dcfSSatish Balay 
125*a7e14dcfSSatish Balay .seealso: TaoSetHessianRoutine(), TaoDefaultComputeHessianColor(), SNESComputeJacobianDefault(), TaoSetGradientRoutine(), TaoDefaultComputeGradient()
126*a7e14dcfSSatish Balay 
127*a7e14dcfSSatish Balay @*/
128*a7e14dcfSSatish Balay PetscErrorCode TaoDefaultComputeHessian(TaoSolver tao,Vec V,Mat *H,Mat *B,
129*a7e14dcfSSatish Balay 			     MatStructure *flag,void *dummy){
130*a7e14dcfSSatish Balay   PetscErrorCode       ierr;
131*a7e14dcfSSatish Balay   MPI_Comm             comm;
132*a7e14dcfSSatish Balay   Vec                  G;
133*a7e14dcfSSatish Balay   SNES                 snes;
134*a7e14dcfSSatish Balay 
135*a7e14dcfSSatish Balay   PetscFunctionBegin;
136*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(V,VEC_CLASSID,2);
137*a7e14dcfSSatish Balay   ierr = VecDuplicate(V,&G);CHKERRQ(ierr);
138*a7e14dcfSSatish Balay 
139*a7e14dcfSSatish Balay   ierr = PetscInfo(tao,"TAO Using finite differences w/o coloring to compute Hessian matrix\n"); CHKERRQ(ierr);
140*a7e14dcfSSatish Balay 
141*a7e14dcfSSatish Balay   ierr = TaoComputeGradient(tao,V,G); CHKERRQ(ierr);
142*a7e14dcfSSatish Balay 
143*a7e14dcfSSatish Balay   ierr = PetscObjectGetComm((PetscObject)(*H),&comm);CHKERRQ(ierr);
144*a7e14dcfSSatish Balay   ierr = SNESCreate(comm,&snes);CHKERRQ(ierr);
145*a7e14dcfSSatish Balay 
146*a7e14dcfSSatish Balay   ierr = SNESSetFunction(snes,G,Fsnes,tao);CHKERRQ(ierr);
147*a7e14dcfSSatish Balay   ierr = SNESComputeJacobianDefault(snes,V,H,B,flag,tao);CHKERRQ(ierr);
148*a7e14dcfSSatish Balay 
149*a7e14dcfSSatish Balay   ierr = SNESDestroy(&snes);CHKERRQ(ierr);
150*a7e14dcfSSatish Balay 
151*a7e14dcfSSatish Balay   ierr = VecDestroy(&G);CHKERRQ(ierr);
152*a7e14dcfSSatish Balay 
153*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
154*a7e14dcfSSatish Balay }
155*a7e14dcfSSatish Balay 
156*a7e14dcfSSatish Balay 
157*a7e14dcfSSatish Balay 
158*a7e14dcfSSatish Balay 
159*a7e14dcfSSatish Balay #undef __FUNCT__
160*a7e14dcfSSatish Balay #define __FUNCT__ "TaoDefaultComputeHessianColor"
161*a7e14dcfSSatish Balay /*@C
162*a7e14dcfSSatish Balay    TaoDefaultComputeHessianColor - Computes the Hessian using colored finite differences.
163*a7e14dcfSSatish Balay 
164*a7e14dcfSSatish Balay    Collective on TaoSolver
165*a7e14dcfSSatish Balay 
166*a7e14dcfSSatish Balay    Input Parameters:
167*a7e14dcfSSatish Balay +  tao - the TaoSolver context
168*a7e14dcfSSatish Balay .  V - compute Hessian at this point
169*a7e14dcfSSatish Balay -  ctx - the PetscColoring object (must be of type MatFDColoring)
170*a7e14dcfSSatish Balay 
171*a7e14dcfSSatish Balay    Output Parameters:
172*a7e14dcfSSatish Balay +  H - Hessian matrix (not altered in this routine)
173*a7e14dcfSSatish Balay .  B - newly computed Hessian matrix to use with preconditioner (generally the same as H)
174*a7e14dcfSSatish Balay -  flag - flag indicating whether the matrix sparsity structure has changed
175*a7e14dcfSSatish Balay 
176*a7e14dcfSSatish Balay    Level: advanced
177*a7e14dcfSSatish Balay 
178*a7e14dcfSSatish Balay 
179*a7e14dcfSSatish Balay .seealso: TaoSetHessianRoutine(), TaoDefaultComputeHessian(),SNESComputeJacobianDefaultColor(), TaoSetGradientRoutine()
180*a7e14dcfSSatish Balay 
181*a7e14dcfSSatish Balay @*/
182*a7e14dcfSSatish Balay PetscErrorCode TaoDefaultComputeHessianColor(TaoSolver tao, Vec V, Mat *H,Mat *B,MatStructure *flag,void *ctx){
183*a7e14dcfSSatish Balay   PetscErrorCode      ierr;
184*a7e14dcfSSatish Balay   MatFDColoring       coloring = (MatFDColoring)ctx;
185*a7e14dcfSSatish Balay 
186*a7e14dcfSSatish Balay   PetscFunctionBegin;
187*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(ctx,MAT_FDCOLORING_CLASSID,6);
188*a7e14dcfSSatish Balay 
189*a7e14dcfSSatish Balay 
190*a7e14dcfSSatish Balay 
191*a7e14dcfSSatish Balay   *flag = SAME_NONZERO_PATTERN;
192*a7e14dcfSSatish Balay 
193*a7e14dcfSSatish Balay   ierr=PetscInfo(tao,"TAO computing matrix using finite differences Hessian and coloring\n"); CHKERRQ(ierr);
194*a7e14dcfSSatish Balay   ierr = MatFDColoringApply(*B,coloring,V,flag,ctx); CHKERRQ(ierr);
195*a7e14dcfSSatish Balay 
196*a7e14dcfSSatish Balay   if (*H != *B) {
197*a7e14dcfSSatish Balay       ierr = MatAssemblyBegin(*H, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
198*a7e14dcfSSatish Balay       ierr = MatAssemblyEnd(*H, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
199*a7e14dcfSSatish Balay   }
200*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
201*a7e14dcfSSatish Balay }
202*a7e14dcfSSatish Balay 
203*a7e14dcfSSatish Balay 
204