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