1af0996ceSBarry Smith #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/ 2a7e14dcfSSatish Balay 3a7e14dcfSSatish Balay /*@ 4a7e14dcfSSatish Balay TaoSetInitialVector - Sets the initial guess for the solve 5a7e14dcfSSatish Balay 6441846f8SBarry Smith Logically collective on Tao 7a7e14dcfSSatish Balay 8a7e14dcfSSatish Balay Input Parameters: 9441846f8SBarry Smith + tao - the Tao context 10a7e14dcfSSatish Balay - x0 - the initial guess 11a7e14dcfSSatish Balay 12a7e14dcfSSatish Balay Level: beginner 13a7e14dcfSSatish Balay .seealso: TaoCreate(), TaoSolve() 14a7e14dcfSSatish Balay @*/ 15a7e14dcfSSatish Balay 16441846f8SBarry Smith PetscErrorCode TaoSetInitialVector(Tao tao, Vec x0) 1745cf516eSBarry Smith { 18a7e14dcfSSatish Balay PetscErrorCode ierr; 19a7e14dcfSSatish Balay 20a7e14dcfSSatish Balay PetscFunctionBegin; 21441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 22a7e14dcfSSatish Balay if (x0) { 23a7e14dcfSSatish Balay PetscValidHeaderSpecific(x0,VEC_CLASSID,2); 24a7e14dcfSSatish Balay PetscObjectReference((PetscObject)x0); 25a7e14dcfSSatish Balay } 26a7e14dcfSSatish Balay ierr = VecDestroy(&tao->solution);CHKERRQ(ierr); 27a7e14dcfSSatish Balay tao->solution = x0; 28a7e14dcfSSatish Balay PetscFunctionReturn(0); 29a7e14dcfSSatish Balay } 30a7e14dcfSSatish Balay 3109baa881SHong Zhang PetscErrorCode TaoTestGradient(Tao tao,Vec g1) 3209baa881SHong Zhang { 3309baa881SHong Zhang Vec x = tao->solution,g2,g3; 3409baa881SHong Zhang PetscBool complete_print = PETSC_FALSE,test = PETSC_FALSE; 3509baa881SHong Zhang PetscReal hcnorm,fdnorm,hcmax,fdmax,diffmax,diffnorm; 3609baa881SHong Zhang PetscScalar dot; 3709baa881SHong Zhang MPI_Comm comm; 3809baa881SHong Zhang PetscViewer viewer; 3909baa881SHong Zhang PetscInt tabs; 4009baa881SHong Zhang static PetscBool directionsprinted = PETSC_FALSE; 4109baa881SHong Zhang PetscErrorCode ierr; 4209baa881SHong Zhang 4309baa881SHong Zhang PetscFunctionBegin; 4409baa881SHong Zhang ierr = PetscObjectOptionsBegin((PetscObject)tao);CHKERRQ(ierr); 4509baa881SHong Zhang ierr = PetscOptionsName("-tao_test_gradient","Compare hand-coded and finite difference Gradients","None",&test);CHKERRQ(ierr); 4609baa881SHong Zhang ierr = PetscOptionsBool("-tao_test_gradient_view","View difference between hand-coded and finite difference Gradients element entries","None",complete_print,&complete_print,NULL);CHKERRQ(ierr); 4709baa881SHong Zhang ierr = PetscOptionsEnd();CHKERRQ(ierr); 4809baa881SHong Zhang if (!test) PetscFunctionReturn(0); 4909baa881SHong Zhang 5009baa881SHong Zhang ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr); 5109baa881SHong Zhang ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr); 5209baa881SHong Zhang ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr); 5309baa881SHong Zhang ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);CHKERRQ(ierr); 5409baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Gradient -------------\n");CHKERRQ(ierr); 5509baa881SHong Zhang if (!complete_print && !directionsprinted) { 5609baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," Run with -tao_test_gradient_view and optionally -tao_test_gradient <threshold> to show difference\n");CHKERRQ(ierr); 5709baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference gradient entries greater than <threshold>.\n");CHKERRQ(ierr); 5809baa881SHong Zhang } 5909baa881SHong Zhang if (!directionsprinted) { 6009baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," Testing hand-coded Gradient, if (for double precision runs) ||G - Gfd||_F/||G||_F is\n");CHKERRQ(ierr); 6109baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Hessian is probably correct.\n");CHKERRQ(ierr); 6209baa881SHong Zhang directionsprinted = PETSC_TRUE; 6309baa881SHong Zhang } 6409baa881SHong Zhang 6509baa881SHong Zhang ierr = VecDuplicate(x,&g2);CHKERRQ(ierr); 6609baa881SHong Zhang ierr = VecDuplicate(x,&g3);CHKERRQ(ierr); 6709baa881SHong Zhang 6809baa881SHong Zhang /* Compute finite difference gradient, assume the gradient is already computed by TaoComputeGradient() and put into g1 */ 6909baa881SHong Zhang ierr = TaoDefaultComputeGradient(tao,x,g2,NULL);CHKERRQ(ierr); 7009baa881SHong Zhang 7109baa881SHong Zhang ierr = VecNorm(g2,NORM_2,&fdnorm);CHKERRQ(ierr); 7209baa881SHong Zhang ierr = VecNorm(g1,NORM_2,&hcnorm);CHKERRQ(ierr); 7309baa881SHong Zhang ierr = VecNorm(g2,NORM_INFINITY,&fdmax);CHKERRQ(ierr); 7409baa881SHong Zhang ierr = VecNorm(g1,NORM_INFINITY,&hcmax);CHKERRQ(ierr); 7509baa881SHong Zhang ierr = VecDot(g1,g2,&dot);CHKERRQ(ierr); 7609baa881SHong Zhang ierr = VecCopy(g1,g3);CHKERRQ(ierr); 7709baa881SHong Zhang ierr = VecAXPY(g3,-1.0,g2);CHKERRQ(ierr); 7809baa881SHong Zhang ierr = VecNorm(g3,NORM_2,&diffnorm);CHKERRQ(ierr); 7909baa881SHong Zhang ierr = VecNorm(g3,NORM_INFINITY,&diffmax);CHKERRQ(ierr); 8009baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," ||Gfd|| %g, ||G|| = %g, angle cosine = (Gfd'G)/||Gfd||||G|| = %g\n", (double)fdnorm, (double)hcnorm, (double)(PetscRealPart(dot)/(fdnorm*hcnorm)));CHKERRQ(ierr); 8109baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," 2-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffnorm/PetscMax(hcnorm,fdnorm)),(double)diffnorm);CHKERRQ(ierr); 8209baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," max-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffmax/PetscMax(hcmax,fdmax)),(double)diffmax);CHKERRQ(ierr); 8309baa881SHong Zhang 8409baa881SHong Zhang if (complete_print) { 8509baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," Hand-coded gradient ----------\n");CHKERRQ(ierr); 8609baa881SHong Zhang ierr = VecView(g1,viewer);CHKERRQ(ierr); 8709baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," Finite difference gradient ----------\n");CHKERRQ(ierr); 8809baa881SHong Zhang ierr = VecView(g2,viewer);CHKERRQ(ierr); 8909baa881SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference gradient ----------\n");CHKERRQ(ierr); 9009baa881SHong Zhang ierr = VecView(g3,viewer);CHKERRQ(ierr); 9109baa881SHong Zhang } 9209baa881SHong Zhang ierr = VecDestroy(&g2);CHKERRQ(ierr); 9309baa881SHong Zhang ierr = VecDestroy(&g3);CHKERRQ(ierr); 9409baa881SHong Zhang PetscFunctionReturn(0); 9509baa881SHong Zhang } 9609baa881SHong Zhang 97a7e14dcfSSatish Balay /*@ 98a7e14dcfSSatish Balay TaoComputeGradient - Computes the gradient of the objective function 99a7e14dcfSSatish Balay 100441846f8SBarry Smith Collective on Tao 101a7e14dcfSSatish Balay 102a7e14dcfSSatish Balay Input Parameters: 103441846f8SBarry Smith + tao - the Tao context 104a7e14dcfSSatish Balay - X - input vector 105a7e14dcfSSatish Balay 106a7e14dcfSSatish Balay Output Parameter: 107a7e14dcfSSatish Balay . G - gradient vector 108a7e14dcfSSatish Balay 10909baa881SHong Zhang Options Database Keys: 11009baa881SHong Zhang + -tao_test_gradient - compare the user provided gradient with one compute via finite differences to check for errors 11109baa881SHong Zhang - -tao_test_gradient_display - display the user provided gradient, the finite difference gradient and the difference between them to help users detect the location of errors in the user provided gradient 11209baa881SHong Zhang 11395452b02SPatrick Sanan Notes: 11495452b02SPatrick Sanan TaoComputeGradient() is typically used within minimization implementations, 115a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 116a7e14dcfSSatish Balay 117a7e14dcfSSatish Balay Level: advanced 118a7e14dcfSSatish Balay 119a7e14dcfSSatish Balay .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetGradientRoutine() 120a7e14dcfSSatish Balay @*/ 121441846f8SBarry Smith PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G) 122a7e14dcfSSatish Balay { 123a7e14dcfSSatish Balay PetscErrorCode ierr; 124a7e14dcfSSatish Balay PetscReal dummy; 12587f595a5SBarry Smith 126a7e14dcfSSatish Balay PetscFunctionBegin; 127441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 128a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 129a7e14dcfSSatish Balay PetscValidHeaderSpecific(G,VEC_CLASSID,2); 130a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 131a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,G,3); 132f4c1ad5cSStefano Zampini ierr = VecLockPush(X);CHKERRQ(ierr); 133a7e14dcfSSatish Balay if (tao->ops->computegradient) { 134441846f8SBarry Smith ierr = PetscLogEventBegin(Tao_GradientEval,tao,X,G,NULL);CHKERRQ(ierr); 135441846f8SBarry Smith PetscStackPush("Tao user gradient evaluation routine"); 136a7e14dcfSSatish Balay ierr = (*tao->ops->computegradient)(tao,X,G,tao->user_gradP);CHKERRQ(ierr); 137a7e14dcfSSatish Balay PetscStackPop; 138441846f8SBarry Smith ierr = PetscLogEventEnd(Tao_GradientEval,tao,X,G,NULL);CHKERRQ(ierr); 139a7e14dcfSSatish Balay tao->ngrads++; 140a7e14dcfSSatish Balay } else if (tao->ops->computeobjectiveandgradient) { 141441846f8SBarry Smith ierr = PetscLogEventBegin(Tao_ObjGradientEval,tao,X,G,NULL);CHKERRQ(ierr); 142a7e14dcfSSatish Balay PetscStackPush("Tao user objective/gradient evaluation routine"); 143a7e14dcfSSatish Balay ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP);CHKERRQ(ierr); 144a7e14dcfSSatish Balay PetscStackPop; 145441846f8SBarry Smith ierr = PetscLogEventEnd(Tao_ObjGradientEval,tao,X,G,NULL);CHKERRQ(ierr); 146a7e14dcfSSatish Balay tao->nfuncgrads++; 14787f595a5SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradientRoutine() has not been called"); 148f4c1ad5cSStefano Zampini ierr = VecLockPop(X);CHKERRQ(ierr); 14909baa881SHong Zhang 15009baa881SHong Zhang ierr = TaoTestGradient(tao,G);CHKERRQ(ierr); 151a7e14dcfSSatish Balay PetscFunctionReturn(0); 152a7e14dcfSSatish Balay } 153a7e14dcfSSatish Balay 154a7e14dcfSSatish Balay /*@ 155a7e14dcfSSatish Balay TaoComputeObjective - Computes the objective function value at a given point 156a7e14dcfSSatish Balay 157441846f8SBarry Smith Collective on Tao 158a7e14dcfSSatish Balay 159a7e14dcfSSatish Balay Input Parameters: 160441846f8SBarry Smith + tao - the Tao context 161a7e14dcfSSatish Balay - X - input vector 162a7e14dcfSSatish Balay 163a7e14dcfSSatish Balay Output Parameter: 164a7e14dcfSSatish Balay . f - Objective value at X 165a7e14dcfSSatish Balay 16695452b02SPatrick Sanan Notes: 16795452b02SPatrick Sanan TaoComputeObjective() is typically used within minimization implementations, 168a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 169a7e14dcfSSatish Balay 170a7e14dcfSSatish Balay Level: advanced 171a7e14dcfSSatish Balay 172a7e14dcfSSatish Balay .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjectiveRoutine() 173a7e14dcfSSatish Balay @*/ 174441846f8SBarry Smith PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f) 175a7e14dcfSSatish Balay { 176a7e14dcfSSatish Balay PetscErrorCode ierr; 177a7e14dcfSSatish Balay Vec temp; 17887f595a5SBarry Smith 179a7e14dcfSSatish Balay PetscFunctionBegin; 180441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 181a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 182a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 183f4c1ad5cSStefano Zampini ierr = VecLockPush(X);CHKERRQ(ierr); 184a7e14dcfSSatish Balay if (tao->ops->computeobjective) { 185441846f8SBarry Smith ierr = PetscLogEventBegin(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr); 186441846f8SBarry Smith PetscStackPush("Tao user objective evaluation routine"); 187a7e14dcfSSatish Balay ierr = (*tao->ops->computeobjective)(tao,X,f,tao->user_objP);CHKERRQ(ierr); 188a7e14dcfSSatish Balay PetscStackPop; 189441846f8SBarry Smith ierr = PetscLogEventEnd(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr); 190a7e14dcfSSatish Balay tao->nfuncs++; 191a7e14dcfSSatish Balay } else if (tao->ops->computeobjectiveandgradient) { 192955c1f14SBarry Smith ierr = PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine\n");CHKERRQ(ierr); 193a7e14dcfSSatish Balay ierr = VecDuplicate(X,&temp);CHKERRQ(ierr); 194441846f8SBarry Smith ierr = PetscLogEventBegin(Tao_ObjGradientEval,tao,X,NULL,NULL);CHKERRQ(ierr); 195441846f8SBarry Smith PetscStackPush("Tao user objective/gradient evaluation routine"); 196a7e14dcfSSatish Balay ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP);CHKERRQ(ierr); 197a7e14dcfSSatish Balay PetscStackPop; 198441846f8SBarry Smith ierr = PetscLogEventEnd(Tao_ObjGradientEval,tao,X,NULL,NULL);CHKERRQ(ierr); 199a7e14dcfSSatish Balay ierr = VecDestroy(&temp);CHKERRQ(ierr); 200a7e14dcfSSatish Balay tao->nfuncgrads++; 20187f595a5SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjectiveRoutine() has not been called"); 202e356b196STodd Munson ierr = PetscInfo1(tao,"TAO Function evaluation: %20.19e\n",(double)(*f));CHKERRQ(ierr); 203f4c1ad5cSStefano Zampini ierr = VecLockPop(X);CHKERRQ(ierr); 204a7e14dcfSSatish Balay PetscFunctionReturn(0); 205a7e14dcfSSatish Balay } 206a7e14dcfSSatish Balay 207a7e14dcfSSatish Balay /*@ 208a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient - Computes the objective function value at a given point 209a7e14dcfSSatish Balay 210441846f8SBarry Smith Collective on Tao 211a7e14dcfSSatish Balay 212a7e14dcfSSatish Balay Input Parameters: 213441846f8SBarry Smith + tao - the Tao context 214a7e14dcfSSatish Balay - X - input vector 215a7e14dcfSSatish Balay 216a7e14dcfSSatish Balay Output Parameter: 217a7e14dcfSSatish Balay + f - Objective value at X 218a7e14dcfSSatish Balay - g - Gradient vector at X 219a7e14dcfSSatish Balay 22095452b02SPatrick Sanan Notes: 22195452b02SPatrick Sanan TaoComputeObjectiveAndGradient() is typically used within minimization implementations, 222a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 223a7e14dcfSSatish Balay 224a7e14dcfSSatish Balay Level: advanced 225a7e14dcfSSatish Balay 226a7e14dcfSSatish Balay .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjectiveRoutine() 227a7e14dcfSSatish Balay @*/ 228441846f8SBarry Smith PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G) 229a7e14dcfSSatish Balay { 230a7e14dcfSSatish Balay PetscErrorCode ierr; 23187f595a5SBarry Smith 232a7e14dcfSSatish Balay PetscFunctionBegin; 233441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 234a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 235a7e14dcfSSatish Balay PetscValidHeaderSpecific(G,VEC_CLASSID,4); 236a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 237a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,G,4); 238f4c1ad5cSStefano Zampini ierr = VecLockPush(X);CHKERRQ(ierr); 239a7e14dcfSSatish Balay if (tao->ops->computeobjectiveandgradient) { 240441846f8SBarry Smith ierr = PetscLogEventBegin(Tao_ObjGradientEval,tao,X,G,NULL);CHKERRQ(ierr); 241f4c1ad5cSStefano Zampini if (tao->ops->computegradient == TaoDefaultComputeGradient) { 242f4c1ad5cSStefano Zampini ierr = TaoComputeObjective(tao,X,f);CHKERRQ(ierr); 243f4c1ad5cSStefano Zampini ierr = TaoDefaultComputeGradient(tao,X,G,NULL);CHKERRQ(ierr); 244f4c1ad5cSStefano Zampini } else { 245441846f8SBarry Smith PetscStackPush("Tao user objective/gradient evaluation routine"); 246a7e14dcfSSatish Balay ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP);CHKERRQ(ierr); 2470cbffdbaSBarry Smith PetscStackPop; 248a7e14dcfSSatish Balay } 249441846f8SBarry Smith ierr = PetscLogEventEnd(Tao_ObjGradientEval,tao,X,G,NULL);CHKERRQ(ierr); 250a7e14dcfSSatish Balay tao->nfuncgrads++; 251a7e14dcfSSatish Balay } else if (tao->ops->computeobjective && tao->ops->computegradient) { 252441846f8SBarry Smith ierr = PetscLogEventBegin(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr); 253441846f8SBarry Smith PetscStackPush("Tao user objective evaluation routine"); 254a7e14dcfSSatish Balay ierr = (*tao->ops->computeobjective)(tao,X,f,tao->user_objP);CHKERRQ(ierr); 255a7e14dcfSSatish Balay PetscStackPop; 256441846f8SBarry Smith ierr = PetscLogEventEnd(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr); 257a7e14dcfSSatish Balay tao->nfuncs++; 258441846f8SBarry Smith ierr = PetscLogEventBegin(Tao_GradientEval,tao,X,G,NULL);CHKERRQ(ierr); 259441846f8SBarry Smith PetscStackPush("Tao user gradient evaluation routine"); 260a7e14dcfSSatish Balay ierr = (*tao->ops->computegradient)(tao,X,G,tao->user_gradP);CHKERRQ(ierr); 261a7e14dcfSSatish Balay PetscStackPop; 262441846f8SBarry Smith ierr = PetscLogEventEnd(Tao_GradientEval,tao,X,G,NULL);CHKERRQ(ierr); 263a7e14dcfSSatish Balay tao->ngrads++; 26487f595a5SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjectiveRoutine() or TaoSetGradientRoutine() not set"); 265e356b196STodd Munson ierr = PetscInfo1(tao,"TAO Function evaluation: %20.19e\n",(double)(*f));CHKERRQ(ierr); 266f4c1ad5cSStefano Zampini ierr = VecLockPop(X);CHKERRQ(ierr); 267*1657496cSHong Zhang 268*1657496cSHong Zhang ierr = TaoTestGradient(tao,G);CHKERRQ(ierr); 269a7e14dcfSSatish Balay PetscFunctionReturn(0); 270a7e14dcfSSatish Balay } 271a7e14dcfSSatish Balay 272a7e14dcfSSatish Balay /*@C 273a7e14dcfSSatish Balay TaoSetObjectiveRoutine - Sets the function evaluation routine for minimization 274a7e14dcfSSatish Balay 275441846f8SBarry Smith Logically collective on Tao 276a7e14dcfSSatish Balay 277a7e14dcfSSatish Balay Input Parameter: 278441846f8SBarry Smith + tao - the Tao context 279a7e14dcfSSatish Balay . func - the objective function 280a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation 2816c23d075SBarry Smith routine (may be NULL) 282a7e14dcfSSatish Balay 283a7e14dcfSSatish Balay Calling sequence of func: 284441846f8SBarry Smith $ func (Tao tao, Vec x, PetscReal *f, void *ctx); 285a7e14dcfSSatish Balay 286a7e14dcfSSatish Balay + x - input vector 287a7e14dcfSSatish Balay . f - function value 288a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 289a7e14dcfSSatish Balay 290a7e14dcfSSatish Balay Level: beginner 291a7e14dcfSSatish Balay 292a7e14dcfSSatish Balay .seealso: TaoSetGradientRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine() 293a7e14dcfSSatish Balay @*/ 294441846f8SBarry Smith PetscErrorCode TaoSetObjectiveRoutine(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal*,void*),void *ctx) 295a7e14dcfSSatish Balay { 296a7e14dcfSSatish Balay PetscFunctionBegin; 297441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 298a7e14dcfSSatish Balay tao->user_objP = ctx; 299a7e14dcfSSatish Balay tao->ops->computeobjective = func; 300a7e14dcfSSatish Balay PetscFunctionReturn(0); 301a7e14dcfSSatish Balay } 302a7e14dcfSSatish Balay 303a7e14dcfSSatish Balay /*@C 304a7e14dcfSSatish Balay TaoSetSeparableObjectiveRoutine - Sets the function evaluation routine for least-square applications 305a7e14dcfSSatish Balay 306441846f8SBarry Smith Logically collective on Tao 307a7e14dcfSSatish Balay 308a7e14dcfSSatish Balay Input Parameter: 309441846f8SBarry Smith + tao - the Tao context 310a7e14dcfSSatish Balay . func - the objective function evaluation routine 311a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation 3126c23d075SBarry Smith routine (may be NULL) 313a7e14dcfSSatish Balay 314a7e14dcfSSatish Balay Calling sequence of func: 315441846f8SBarry Smith $ func (Tao tao, Vec x, Vec f, void *ctx); 316a7e14dcfSSatish Balay 317a7e14dcfSSatish Balay + x - input vector 318a7e14dcfSSatish Balay . f - function value vector 319a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 320a7e14dcfSSatish Balay 321a7e14dcfSSatish Balay Level: beginner 322a7e14dcfSSatish Balay 323a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoSetJacobianRoutine() 324a7e14dcfSSatish Balay @*/ 325441846f8SBarry Smith PetscErrorCode TaoSetSeparableObjectiveRoutine(Tao tao, Vec sepobj, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx) 326a7e14dcfSSatish Balay { 327a7e14dcfSSatish Balay PetscFunctionBegin; 328441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 329a7e14dcfSSatish Balay PetscValidHeaderSpecific(sepobj, VEC_CLASSID,2); 330a7e14dcfSSatish Balay tao->user_sepobjP = ctx; 331a7e14dcfSSatish Balay tao->sep_objective = sepobj; 332a7e14dcfSSatish Balay tao->ops->computeseparableobjective = func; 333a7e14dcfSSatish Balay PetscFunctionReturn(0); 334a7e14dcfSSatish Balay } 335a7e14dcfSSatish Balay 3368b7a9b22SJason Sarich /*@ 3378b7a9b22SJason Sarich TaoSetSeparableObjectiveWeights - Give weights for the separable objective values. A vector can be used if only diagonal terms are used, otherwise a matrix can be give. If this function is not used, or if sigma_v and sigma_w are both NULL, then the default identity matrix will be used for weights. 3388b7a9b22SJason Sarich 3398b7a9b22SJason Sarich Collective on Tao 3408b7a9b22SJason Sarich 3418b7a9b22SJason Sarich Input Parameters: 3428b7a9b22SJason Sarich + tao - the Tao context 3438b7a9b22SJason Sarich . sigma_v - vector of weights (diagonal terms only) 3448b7a9b22SJason Sarich . n - the number of weights (if using off-diagonal) 3458b7a9b22SJason Sarich . rows - index list of rows for sigma_w 3468b7a9b22SJason Sarich . cols - index list of columns for sigma_w 3478b7a9b22SJason Sarich - vals - array of weights 3488b7a9b22SJason Sarich 3498b7a9b22SJason Sarich 3508b7a9b22SJason Sarich 3518b7a9b22SJason Sarich Note: Either sigma_v or sigma_w (or both) should be NULL 3528b7a9b22SJason Sarich 3538b7a9b22SJason Sarich Level: intermediate 3548b7a9b22SJason Sarich 3558b7a9b22SJason Sarich .seealso: TaoSetSeparableObjectiveRoutine() 3568b7a9b22SJason Sarich @*/ 3578b7a9b22SJason Sarich PetscErrorCode TaoSetSeparableObjectiveWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals) 3588b7a9b22SJason Sarich { 3598b7a9b22SJason Sarich PetscErrorCode ierr; 3608b7a9b22SJason Sarich PetscInt i; 3618b7a9b22SJason Sarich PetscFunctionBegin; 3628b7a9b22SJason Sarich PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 3638b7a9b22SJason Sarich ierr = VecDestroy(&tao->sep_weights_v);CHKERRQ(ierr); 3648b7a9b22SJason Sarich tao->sep_weights_v=sigma_v; 3658b7a9b22SJason Sarich if (sigma_v) { 3668b7a9b22SJason Sarich ierr = PetscObjectReference((PetscObject)sigma_v);CHKERRQ(ierr); 3678b7a9b22SJason Sarich } 3688b7a9b22SJason Sarich if (vals) { 3698b7a9b22SJason Sarich if (tao->sep_weights_n) { 3708b7a9b22SJason Sarich ierr = PetscFree(tao->sep_weights_rows);CHKERRQ(ierr); 3718b7a9b22SJason Sarich ierr = PetscFree(tao->sep_weights_cols);CHKERRQ(ierr); 3728b7a9b22SJason Sarich ierr = PetscFree(tao->sep_weights_w);CHKERRQ(ierr); 3738b7a9b22SJason Sarich } 3748b7a9b22SJason Sarich ierr = PetscMalloc1(n,&tao->sep_weights_rows);CHKERRQ(ierr); 3758b7a9b22SJason Sarich ierr = PetscMalloc1(n,&tao->sep_weights_cols);CHKERRQ(ierr); 3768b7a9b22SJason Sarich ierr = PetscMalloc1(n,&tao->sep_weights_w);CHKERRQ(ierr); 3778b7a9b22SJason Sarich tao->sep_weights_n=n; 3788b7a9b22SJason Sarich for (i=0;i<n;i++) { 3798b7a9b22SJason Sarich tao->sep_weights_rows[i]=rows[i]; 3808b7a9b22SJason Sarich tao->sep_weights_cols[i]=cols[i]; 3818b7a9b22SJason Sarich tao->sep_weights_w[i]=vals[i]; 3828b7a9b22SJason Sarich } 3838b7a9b22SJason Sarich } else { 3848b7a9b22SJason Sarich tao->sep_weights_n=0; 3858b7a9b22SJason Sarich tao->sep_weights_rows=0; 3868b7a9b22SJason Sarich tao->sep_weights_cols=0; 3878b7a9b22SJason Sarich } 3888b7a9b22SJason Sarich PetscFunctionReturn(0); 3898b7a9b22SJason Sarich } 390a7e14dcfSSatish Balay /*@ 391a7e14dcfSSatish Balay TaoComputeSeparableObjective - Computes a separable objective function vector at a given point (for least-square applications) 392a7e14dcfSSatish Balay 393441846f8SBarry Smith Collective on Tao 394a7e14dcfSSatish Balay 395a7e14dcfSSatish Balay Input Parameters: 396441846f8SBarry Smith + tao - the Tao context 397a7e14dcfSSatish Balay - X - input vector 398a7e14dcfSSatish Balay 399a7e14dcfSSatish Balay Output Parameter: 400a7e14dcfSSatish Balay . f - Objective vector at X 401a7e14dcfSSatish Balay 40295452b02SPatrick Sanan Notes: 40395452b02SPatrick Sanan TaoComputeSeparableObjective() is typically used within minimization implementations, 404a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 405a7e14dcfSSatish Balay 406a7e14dcfSSatish Balay Level: advanced 407a7e14dcfSSatish Balay 408a7e14dcfSSatish Balay .seealso: TaoSetSeparableObjectiveRoutine() 409a7e14dcfSSatish Balay @*/ 410441846f8SBarry Smith PetscErrorCode TaoComputeSeparableObjective(Tao tao, Vec X, Vec F) 411a7e14dcfSSatish Balay { 412a7e14dcfSSatish Balay PetscErrorCode ierr; 41387f595a5SBarry Smith 414a7e14dcfSSatish Balay PetscFunctionBegin; 415441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 416a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 417a7e14dcfSSatish Balay PetscValidHeaderSpecific(F,VEC_CLASSID,3); 418a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 419a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,F,3); 420a7e14dcfSSatish Balay if (tao->ops->computeseparableobjective) { 421441846f8SBarry Smith ierr = PetscLogEventBegin(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr); 422441846f8SBarry Smith PetscStackPush("Tao user separable objective evaluation routine"); 423a7e14dcfSSatish Balay ierr = (*tao->ops->computeseparableobjective)(tao,X,F,tao->user_sepobjP);CHKERRQ(ierr); 424a7e14dcfSSatish Balay PetscStackPop; 425441846f8SBarry Smith ierr = PetscLogEventEnd(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr); 426a7e14dcfSSatish Balay tao->nfuncs++; 42787f595a5SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetSeparableObjectiveRoutine() has not been called"); 428a7e14dcfSSatish Balay ierr = PetscInfo(tao,"TAO separable function evaluation.\n");CHKERRQ(ierr); 429a7e14dcfSSatish Balay PetscFunctionReturn(0); 430a7e14dcfSSatish Balay } 431a7e14dcfSSatish Balay 432a7e14dcfSSatish Balay /*@C 433a7e14dcfSSatish Balay TaoSetGradientRoutine - Sets the gradient evaluation routine for minimization 434a7e14dcfSSatish Balay 435441846f8SBarry Smith Logically collective on Tao 436a7e14dcfSSatish Balay 437a7e14dcfSSatish Balay Input Parameter: 438441846f8SBarry Smith + tao - the Tao context 439a7e14dcfSSatish Balay . func - the gradient function 440a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 4416c23d075SBarry Smith routine (may be NULL) 442a7e14dcfSSatish Balay 443a7e14dcfSSatish Balay Calling sequence of func: 444441846f8SBarry Smith $ func (Tao tao, Vec x, Vec g, void *ctx); 445a7e14dcfSSatish Balay 446a7e14dcfSSatish Balay + x - input vector 447a7e14dcfSSatish Balay . g - gradient value (output) 448a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 449a7e14dcfSSatish Balay 450a7e14dcfSSatish Balay Level: beginner 451a7e14dcfSSatish Balay 452a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine() 453a7e14dcfSSatish Balay @*/ 454441846f8SBarry Smith PetscErrorCode TaoSetGradientRoutine(Tao tao, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx) 455a7e14dcfSSatish Balay { 456a7e14dcfSSatish Balay PetscFunctionBegin; 457441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 458a7e14dcfSSatish Balay tao->user_gradP = ctx; 459a7e14dcfSSatish Balay tao->ops->computegradient = func; 460a7e14dcfSSatish Balay PetscFunctionReturn(0); 461a7e14dcfSSatish Balay } 462a7e14dcfSSatish Balay 463a7e14dcfSSatish Balay /*@C 464a7e14dcfSSatish Balay TaoSetObjectiveAndGradientRoutine - Sets a combined objective function and gradient evaluation routine for minimization 465a7e14dcfSSatish Balay 466441846f8SBarry Smith Logically collective on Tao 467a7e14dcfSSatish Balay 468a7e14dcfSSatish Balay Input Parameter: 469441846f8SBarry Smith + tao - the Tao context 470a7e14dcfSSatish Balay . func - the gradient function 471a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 4726c23d075SBarry Smith routine (may be NULL) 473a7e14dcfSSatish Balay 474a7e14dcfSSatish Balay Calling sequence of func: 47517477c02SJason Sarich $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 476a7e14dcfSSatish Balay 477a7e14dcfSSatish Balay + x - input vector 47817477c02SJason Sarich . f - objective value (output) 479a7e14dcfSSatish Balay . g - gradient value (output) 480a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 481a7e14dcfSSatish Balay 482a7e14dcfSSatish Balay Level: beginner 483a7e14dcfSSatish Balay 484a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine() 485a7e14dcfSSatish Balay @*/ 486441846f8SBarry Smith PetscErrorCode TaoSetObjectiveAndGradientRoutine(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal *, Vec, void*), void *ctx) 487a7e14dcfSSatish Balay { 488a7e14dcfSSatish Balay PetscFunctionBegin; 489441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 490a7e14dcfSSatish Balay tao->user_objgradP = ctx; 491a7e14dcfSSatish Balay tao->ops->computeobjectiveandgradient = func; 492a7e14dcfSSatish Balay PetscFunctionReturn(0); 493a7e14dcfSSatish Balay } 494a7e14dcfSSatish Balay 495a7e14dcfSSatish Balay /*@ 496a7e14dcfSSatish Balay TaoIsObjectiveDefined -- Checks to see if the user has 497a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 498a7e14dcfSSatish Balay it is appropriate to call TaoComputeObjective() or 499a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient() 500a7e14dcfSSatish Balay 501441846f8SBarry Smith Collective on Tao 502a7e14dcfSSatish Balay 503a7e14dcfSSatish Balay Input Parameter: 504441846f8SBarry Smith + tao - the Tao context 505a7e14dcfSSatish Balay - ctx - PETSC_TRUE if objective function routine is set by user, 506a7e14dcfSSatish Balay PETSC_FALSE otherwise 507a7e14dcfSSatish Balay Level: developer 508a7e14dcfSSatish Balay 509a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoIsGradientDefined(), TaoIsObjectiveAndGradientDefined() 510a7e14dcfSSatish Balay @*/ 511441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg) 512a7e14dcfSSatish Balay { 513a7e14dcfSSatish Balay PetscFunctionBegin; 514441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 51545cf516eSBarry Smith if (tao->ops->computeobjective == 0) *flg = PETSC_FALSE; 51645cf516eSBarry Smith else *flg = PETSC_TRUE; 517a7e14dcfSSatish Balay PetscFunctionReturn(0); 518a7e14dcfSSatish Balay } 519a7e14dcfSSatish Balay 520a7e14dcfSSatish Balay /*@ 521a7e14dcfSSatish Balay TaoIsGradientDefined -- Checks to see if the user has 522a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 523a7e14dcfSSatish Balay it is appropriate to call TaoComputeGradient() or 524a7e14dcfSSatish Balay TaoComputeGradientAndGradient() 525a7e14dcfSSatish Balay 526a7e14dcfSSatish Balay Not Collective 527a7e14dcfSSatish Balay 528a7e14dcfSSatish Balay Input Parameter: 529441846f8SBarry Smith + tao - the Tao context 530a7e14dcfSSatish Balay - ctx - PETSC_TRUE if gradient routine is set by user, PETSC_FALSE otherwise 531a7e14dcfSSatish Balay Level: developer 532a7e14dcfSSatish Balay 533a7e14dcfSSatish Balay .seealso: TaoSetGradientRoutine(), TaoIsObjectiveDefined(), TaoIsObjectiveAndGradientDefined() 534a7e14dcfSSatish Balay @*/ 535441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg) 536a7e14dcfSSatish Balay { 537a7e14dcfSSatish Balay PetscFunctionBegin; 538441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 53945cf516eSBarry Smith if (tao->ops->computegradient == 0) *flg = PETSC_FALSE; 54045cf516eSBarry Smith else *flg = PETSC_TRUE; 541a7e14dcfSSatish Balay PetscFunctionReturn(0); 542a7e14dcfSSatish Balay } 543a7e14dcfSSatish Balay 544a7e14dcfSSatish Balay /*@ 545a7e14dcfSSatish Balay TaoIsObjectiveAndGradientDefined -- Checks to see if the user has 546a7e14dcfSSatish Balay declared a joint objective/gradient routine. Useful for determining when 547a7e14dcfSSatish Balay it is appropriate to call TaoComputeObjective() or 548a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient() 549a7e14dcfSSatish Balay 550a7e14dcfSSatish Balay Not Collective 551a7e14dcfSSatish Balay 552a7e14dcfSSatish Balay Input Parameter: 553441846f8SBarry Smith + tao - the Tao context 554a7e14dcfSSatish Balay - ctx - PETSC_TRUE if objective/gradient routine is set by user, PETSC_FALSE otherwise 555a7e14dcfSSatish Balay Level: developer 556a7e14dcfSSatish Balay 557a7e14dcfSSatish Balay .seealso: TaoSetObjectiveAndGradientRoutine(), TaoIsObjectiveDefined(), TaoIsGradientDefined() 558a7e14dcfSSatish Balay @*/ 559441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg) 560a7e14dcfSSatish Balay { 561a7e14dcfSSatish Balay PetscFunctionBegin; 562441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 56345cf516eSBarry Smith if (tao->ops->computeobjectiveandgradient == 0) *flg = PETSC_FALSE; 56445cf516eSBarry Smith else *flg = PETSC_TRUE; 565a7e14dcfSSatish Balay PetscFunctionReturn(0); 566a7e14dcfSSatish Balay } 567