1c4762a1bSJed Brown! Program usage: mpiexec -n 1 rosenbrock1f [-help] [all TAO options] 2c4762a1bSJed Brown! 3c4762a1bSJed Brown! Description: This example demonstrates use of the TAO package to solve an 4c4762a1bSJed Brown! unconstrained minimization problem on a single processor. We minimize the 5c4762a1bSJed Brown! extended Rosenbrock function: 6c4762a1bSJed Brown! sum_{i=0}^{n/2-1} (alpha*(x_{2i+1}-x_{2i}^2)^2 + (1-x_{2i})^2) 7c4762a1bSJed Brown! 8c4762a1bSJed Brown! The C version of this code is rosenbrock1.c 9c4762a1bSJed Brown! 10c4762a1bSJed Brown 11c4762a1bSJed Brown! 12c4762a1bSJed Brown 13c4762a1bSJed Brown! ---------------------------------------------------------------------- 14c4762a1bSJed Brown! 15c4762a1bSJed Brown#include "rosenbrock1f.h" 16c4762a1bSJed Brown 17c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 18c4762a1bSJed Brown! Variable declarations 19c4762a1bSJed Brown! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 20c4762a1bSJed Brown! 21c4762a1bSJed Brown! See additional variable declarations in the file rosenbrock1f.h 22c4762a1bSJed Brown 23c4762a1bSJed Brown PetscErrorCode ierr ! used to check for functions returning nonzeros 24c4762a1bSJed Brown Vec x ! solution vector 25c4762a1bSJed Brown Mat H ! hessian matrix 26c4762a1bSJed Brown Tao tao ! TAO_SOVER context 27c4762a1bSJed Brown PetscBool flg 28c4762a1bSJed Brown PetscInt i2,i1 29c4762a1bSJed Brown PetscMPIInt size 30c4762a1bSJed Brown PetscReal zero 31c4762a1bSJed Brown 32c4762a1bSJed Brown! Note: Any user-defined Fortran routines (such as FormGradient) 33c4762a1bSJed Brown! MUST be declared as external. 34c4762a1bSJed Brown 35c4762a1bSJed Brown external FormFunctionGradient,FormHessian 36c4762a1bSJed Brown 37c4762a1bSJed Brown zero = 0.0d0 38c4762a1bSJed Brown i2 = 2 39c4762a1bSJed Brown i1 = 1 40c4762a1bSJed Brown 41c4762a1bSJed Brown! Initialize TAO and PETSc 42*d8606c27SBarry Smith PetscCallA(PetscInitialize(ierr)) 43c4762a1bSJed Brown 44*d8606c27SBarry Smith PetscCallMPIA(MPI_Comm_size(PETSC_COMM_WORLD,size,ierr)) 45c4762a1bSJed Brown if (size .ne. 1) then; SETERRA(PETSC_COMM_SELF,PETSC_ERR_WRONG_MPI_SIZE,'This is a uniprocessor example only'); endif 46c4762a1bSJed Brown 47c4762a1bSJed Brown! Initialize problem parameters 48c4762a1bSJed Brown n = 2 49c4762a1bSJed Brown alpha = 99.0d0 50c4762a1bSJed Brown 51c4762a1bSJed Brown! Check for command line arguments to override defaults 52*d8606c27SBarry Smith PetscCallA(PetscOptionsGetInt(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-n',n,flg,ierr)) 53*d8606c27SBarry Smith PetscCallA(PetscOptionsGetReal(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-alpha',alpha,flg,ierr)) 54c4762a1bSJed Brown 55c4762a1bSJed Brown! Allocate vectors for the solution and gradient 56*d8606c27SBarry Smith PetscCallA(VecCreateSeq(PETSC_COMM_SELF,n,x,ierr)) 57c4762a1bSJed Brown 58c4762a1bSJed Brown! Allocate storage space for Hessian; 59*d8606c27SBarry Smith PetscCallA(MatCreateSeqBAIJ(PETSC_COMM_SELF,i2,n,n,i1,PETSC_NULL_INTEGER, H,ierr)) 60c4762a1bSJed Brown 61*d8606c27SBarry Smith PetscCallA(MatSetOption(H,MAT_SYMMETRIC,PETSC_TRUE,ierr)) 62c4762a1bSJed Brown 63c4762a1bSJed Brown! The TAO code begins here 64c4762a1bSJed Brown 65c4762a1bSJed Brown! Create TAO solver 66*d8606c27SBarry Smith PetscCallA(TaoCreate(PETSC_COMM_SELF,tao,ierr)) 67*d8606c27SBarry Smith PetscCallA(TaoSetType(tao,TAOLMVM,ierr)) 68c4762a1bSJed Brown 69c4762a1bSJed Brown! Set routines for function, gradient, and hessian evaluation 70*d8606c27SBarry Smith PetscCallA(TaoSetObjectiveAndGradient(tao,PETSC_NULL_VEC,FormFunctionGradient,0,ierr)) 71*d8606c27SBarry Smith PetscCallA(TaoSetHessian(tao,H,H,FormHessian,0,ierr)) 72c4762a1bSJed Brown 73c4762a1bSJed Brown! Optional: Set initial guess 74*d8606c27SBarry Smith PetscCallA(VecSet(x, zero, ierr)) 75*d8606c27SBarry Smith PetscCallA(TaoSetSolution(tao, x, ierr)) 76c4762a1bSJed Brown 77c4762a1bSJed Brown! Check for TAO command line options 78*d8606c27SBarry Smith PetscCallA(TaoSetFromOptions(tao,ierr)) 79c4762a1bSJed Brown 80c4762a1bSJed Brown! SOLVE THE APPLICATION 81*d8606c27SBarry Smith PetscCallA(TaoSolve(tao,ierr)) 82c4762a1bSJed Brown 83c4762a1bSJed Brown! TaoView() prints ierr about the TAO solver; the option 84c4762a1bSJed Brown! -tao_view 85c4762a1bSJed Brown! can alternatively be used to activate this at runtime. 86*d8606c27SBarry Smith! PetscCallA(TaoView(tao,PETSC_VIEWER_STDOUT_SELF,ierr)) 87c4762a1bSJed Brown 88c4762a1bSJed Brown! Free TAO data structures 89*d8606c27SBarry Smith PetscCallA(TaoDestroy(tao,ierr)) 90c4762a1bSJed Brown 91c4762a1bSJed Brown! Free PETSc data structures 92*d8606c27SBarry Smith PetscCallA(VecDestroy(x,ierr)) 93*d8606c27SBarry Smith PetscCallA(MatDestroy(H,ierr)) 94c4762a1bSJed Brown 95*d8606c27SBarry Smith PetscCallA(PetscFinalize(ierr)) 96c4762a1bSJed Brown end 97c4762a1bSJed Brown 98c4762a1bSJed Brown! -------------------------------------------------------------------- 99c4762a1bSJed Brown! FormFunctionGradient - Evaluates the function f(X) and gradient G(X) 100c4762a1bSJed Brown! 101c4762a1bSJed Brown! Input Parameters: 102c4762a1bSJed Brown! tao - the Tao context 103c4762a1bSJed Brown! X - input vector 104c4762a1bSJed Brown! dummy - not used 105c4762a1bSJed Brown! 106c4762a1bSJed Brown! Output Parameters: 107c4762a1bSJed Brown! G - vector containing the newly evaluated gradient 108c4762a1bSJed Brown! f - function value 109c4762a1bSJed Brown 110c4762a1bSJed Brown subroutine FormFunctionGradient(tao, X, f, G, dummy, ierr) 111c4762a1bSJed Brown#include "rosenbrock1f.h" 112c4762a1bSJed Brown 113c4762a1bSJed Brown Tao tao 114c4762a1bSJed Brown Vec X,G 115c4762a1bSJed Brown PetscReal f 116c4762a1bSJed Brown PetscErrorCode ierr 117c4762a1bSJed Brown PetscInt dummy 118c4762a1bSJed Brown 119c4762a1bSJed Brown PetscReal ff,t1,t2 120c4762a1bSJed Brown PetscInt i,nn 121c4762a1bSJed Brown 122c4762a1bSJed Brown! PETSc's VecGetArray acts differently in Fortran than it does in C. 123c4762a1bSJed Brown! Calling VecGetArray((Vec) X, (PetscReal) x_array(0:1), (PetscOffset) x_index, ierr) 124c4762a1bSJed Brown! will return an array of doubles referenced by x_array offset by x_index. 125c4762a1bSJed Brown! i.e., to reference the kth element of X, use x_array(k + x_index). 126c4762a1bSJed Brown! Notice that by declaring the arrays with range (0:1), we are using the C 0-indexing practice. 127c4762a1bSJed Brown PetscReal g_v(0:1),x_v(0:1) 128c4762a1bSJed Brown PetscOffset g_i,x_i 129c4762a1bSJed Brown 130c4762a1bSJed Brown ierr = 0 131c4762a1bSJed Brown nn = n/2 132c4762a1bSJed Brown ff = 0 133c4762a1bSJed Brown 134c4762a1bSJed Brown! Get pointers to vector data 135*d8606c27SBarry Smith PetscCall(VecGetArrayRead(X,x_v,x_i,ierr)) 136*d8606c27SBarry Smith PetscCall(VecGetArray(G,g_v,g_i,ierr)) 137c4762a1bSJed Brown 138c4762a1bSJed Brown! Compute G(X) 139c4762a1bSJed Brown do i=0,nn-1 140c4762a1bSJed Brown t1 = x_v(x_i+2*i+1) - x_v(x_i+2*i)*x_v(x_i+2*i) 141c4762a1bSJed Brown t2 = 1.0 - x_v(x_i + 2*i) 142c4762a1bSJed Brown ff = ff + alpha*t1*t1 + t2*t2 143c4762a1bSJed Brown g_v(g_i + 2*i) = -4*alpha*t1*x_v(x_i + 2*i) - 2.0*t2 144c4762a1bSJed Brown g_v(g_i + 2*i + 1) = 2.0*alpha*t1 145c4762a1bSJed Brown enddo 146c4762a1bSJed Brown 147c4762a1bSJed Brown! Restore vectors 148*d8606c27SBarry Smith PetscCall(VecRestoreArrayRead(X,x_v,x_i,ierr)) 149*d8606c27SBarry Smith PetscCall(VecRestoreArray(G,g_v,g_i,ierr)) 150c4762a1bSJed Brown 151c4762a1bSJed Brown f = ff 152*d8606c27SBarry Smith PetscCall(PetscLogFlops(15.0d0*nn,ierr)) 153c4762a1bSJed Brown 154c4762a1bSJed Brown return 155c4762a1bSJed Brown end 156c4762a1bSJed Brown 157c4762a1bSJed Brown! 158c4762a1bSJed Brown! --------------------------------------------------------------------- 159c4762a1bSJed Brown! 160c4762a1bSJed Brown! FormHessian - Evaluates Hessian matrix. 161c4762a1bSJed Brown! 162c4762a1bSJed Brown! Input Parameters: 163c4762a1bSJed Brown! tao - the Tao context 164c4762a1bSJed Brown! X - input vector 165c4762a1bSJed Brown! dummy - optional user-defined context, as set by SNESSetHessian() 166c4762a1bSJed Brown! (not used here) 167c4762a1bSJed Brown! 168c4762a1bSJed Brown! Output Parameters: 169c4762a1bSJed Brown! H - Hessian matrix 170c4762a1bSJed Brown! PrecH - optionally different preconditioning matrix (not used here) 171c4762a1bSJed Brown! flag - flag indicating matrix structure 172c4762a1bSJed Brown! ierr - error code 173c4762a1bSJed Brown! 174c4762a1bSJed Brown! Note: Providing the Hessian may not be necessary. Only some solvers 175c4762a1bSJed Brown! require this matrix. 176c4762a1bSJed Brown 177c4762a1bSJed Brown subroutine FormHessian(tao,X,H,PrecH,dummy,ierr) 178c4762a1bSJed Brown#include "rosenbrock1f.h" 179c4762a1bSJed Brown 180c4762a1bSJed Brown! Input/output variables: 181c4762a1bSJed Brown Tao tao 182c4762a1bSJed Brown Vec X 183c4762a1bSJed Brown Mat H, PrecH 184c4762a1bSJed Brown PetscErrorCode ierr 185c4762a1bSJed Brown PetscInt dummy 186c4762a1bSJed Brown 187c4762a1bSJed Brown PetscReal v(0:1,0:1) 188c4762a1bSJed Brown PetscBool assembled 189c4762a1bSJed Brown 190c4762a1bSJed Brown! PETSc's VecGetArray acts differently in Fortran than it does in C. 191c4762a1bSJed Brown! Calling VecGetArray((Vec) X, (PetscReal) x_array(0:1), (PetscOffset) x_index, ierr) 192c4762a1bSJed Brown! will return an array of doubles referenced by x_array offset by x_index. 193c4762a1bSJed Brown! i.e., to reference the kth element of X, use x_array(k + x_index). 194c4762a1bSJed Brown! Notice that by declaring the arrays with range (0:1), we are using the C 0-indexing practice. 195c4762a1bSJed Brown PetscReal x_v(0:1) 196c4762a1bSJed Brown PetscOffset x_i 197c4762a1bSJed Brown PetscInt i,nn,ind(0:1),i2 198c4762a1bSJed Brown 199c4762a1bSJed Brown ierr = 0 200c4762a1bSJed Brown nn= n/2 201c4762a1bSJed Brown i2 = 2 202c4762a1bSJed Brown 203c4762a1bSJed Brown! Zero existing matrix entries 204*d8606c27SBarry Smith PetscCall(MatAssembled(H,assembled,ierr)) 205*d8606c27SBarry Smith if (assembled .eqv. PETSC_TRUE) PetscCall(MatZeroEntries(H,ierr)) 206c4762a1bSJed Brown 207c4762a1bSJed Brown! Get a pointer to vector data 208c4762a1bSJed Brown 209*d8606c27SBarry Smith PetscCall(VecGetArrayRead(X,x_v,x_i,ierr)) 210c4762a1bSJed Brown 211c4762a1bSJed Brown! Compute Hessian entries 212c4762a1bSJed Brown 213c4762a1bSJed Brown do i=0,nn-1 214c4762a1bSJed Brown v(1,1) = 2.0*alpha 215*d8606c27SBarry Smith v(0,0) = -4.0*alpha*(x_v(x_i+2*i+1) - 3*x_v(x_i+2*i)*x_v(x_i+2*i))+2 216c4762a1bSJed Brown v(1,0) = -4.0*alpha*x_v(x_i+2*i) 217c4762a1bSJed Brown v(0,1) = v(1,0) 218c4762a1bSJed Brown ind(0) = 2*i 219c4762a1bSJed Brown ind(1) = 2*i + 1 220*d8606c27SBarry Smith PetscCall(MatSetValues(H,i2,ind,i2,ind,v,INSERT_VALUES,ierr)) 221c4762a1bSJed Brown enddo 222c4762a1bSJed Brown 223c4762a1bSJed Brown! Restore vector 224c4762a1bSJed Brown 225*d8606c27SBarry Smith PetscCall(VecRestoreArrayRead(X,x_v,x_i,ierr)) 226c4762a1bSJed Brown 227c4762a1bSJed Brown! Assemble matrix 228c4762a1bSJed Brown 229*d8606c27SBarry Smith PetscCall(MatAssemblyBegin(H,MAT_FINAL_ASSEMBLY,ierr)) 230*d8606c27SBarry Smith PetscCall(MatAssemblyEnd(H,MAT_FINAL_ASSEMBLY,ierr)) 231c4762a1bSJed Brown 232*d8606c27SBarry Smith PetscCall(PetscLogFlops(9.0d0*nn,ierr)) 233c4762a1bSJed Brown 234c4762a1bSJed Brown return 235c4762a1bSJed Brown end 236c4762a1bSJed Brown 237c4762a1bSJed Brown! 238c4762a1bSJed Brown!/*TEST 239c4762a1bSJed Brown! 240c4762a1bSJed Brown! build: 241c4762a1bSJed Brown! requires: !complex 242c4762a1bSJed Brown! 243c4762a1bSJed Brown! test: 244c4762a1bSJed Brown! args: -tao_smonitor -tao_type ntr -tao_gatol 1.e-5 245c4762a1bSJed Brown! requires: !single 246c4762a1bSJed Brown! 247c4762a1bSJed Brown!TEST*/ 248