Ipopt
trunk
|
00001 00009 package org.coinor.examples.scalable; 00010 00017 public class LuksanVlcek1 extends Scalable 00018 { 00024 public LuksanVlcek1(String name, double gl, double gu) 00025 { 00026 super(name, gl, gu); 00027 } 00028 00029 @Override 00030 public boolean initialize(int n) 00031 { 00032 if( n <= 2 ) 00033 { 00034 System.out.print("N needs to be at least 3.\n"); 00035 return false; 00036 } 00037 00038 // The problem described in LuksanVlcek1.hpp has 4 variables, x[0] through x[3] 00039 this.n = n; 00040 00041 m = n - 2; 00042 00043 nnz_jac_g = m * 3; 00044 00045 nnz_h_lag = n + n-1; 00046 00047 // use the C style numbering of matrix indices (starting at 0) 00048 index_style = C_STYLE; 00049 00050 // none of the variables have bounds 00051 x_l = new double[n]; 00052 x_u = new double[n]; 00053 for( int i = 0; i < n; ++i ) 00054 { 00055 x_l[i] = -1e20; 00056 x_u[i] = 1e20; 00057 } 00058 00059 // Set the bounds for the constraints 00060 g_l = new double[m]; 00061 g_u = new double[m]; 00062 for( int i = 0; i < m; ++i ) 00063 { 00064 g_l[i] = gl; 00065 g_u[i] = gu; 00066 } 00067 00068 // set the starting point 00069 x = new double[n]; 00070 for( int i = 0; i < n/2; ++i ) 00071 { 00072 x[2*i] = -1.2; 00073 x[2*i+1] = 1.0; 00074 } 00075 if( n % 2 == 1 ) 00076 x[n-1] = -1.2; 00077 00078 return true; 00079 } 00080 00081 protected boolean get_bounds_info(int n, double[] x_l, double[] x_u, 00082 int m, double[] g_l, double[] g_u) 00083 { 00084 // none of the variables have bounds 00085 for( int i = 0; i < n; ++i ) 00086 { 00087 x_l[i] = -1e20; 00088 x_u[i] = 1e20; 00089 } 00090 00091 // Set the bounds for the constraints 00092 for( int i = 0; i < m; ++i ) 00093 { 00094 g_l[i] = gl; 00095 g_u[i] = gu; 00096 } 00097 00098 return true; 00099 } 00100 00101 protected boolean get_starting_point(int n, boolean init_x, double[] x, 00102 boolean init_z, double[] z_L, double[] z_U, 00103 int m, boolean init_lambda,double[] lambda) 00104 { 00105 for( int i = 0; i < n/2; ++i ) 00106 { 00107 x[2*i] = -1.2; 00108 x[2*i+1] = 1.0; 00109 } 00110 if( n % 2 == 1 ) 00111 x[n-1] = -1.2; 00112 00113 return true; 00114 } 00115 00116 @Override 00117 protected boolean eval_f(int n, double[] x, boolean new_x, double[] obj_value) 00118 { 00119 obj_value[0] = 0.0; 00120 for( int i = 0; i < n-1; ++i ) 00121 { 00122 double a1 = x[i] * x[i] - x[i+1]; 00123 double a2 = x[i] - 1.0; 00124 obj_value[0] += 100.0 * a1 * a1 + a2 * a2; 00125 } 00126 00127 return true; 00128 } 00129 00130 @Override 00131 protected boolean eval_g(int n, double[] x, boolean new_x, int m, double[] g) 00132 { 00133 for( int i = 0; i < n-2; ++i ) 00134 g[i] = 3.0 * Math.pow(x[i+1], 3.0) + 2.0 * x[i+2] - 5.0 + Math.sin(x[i+1]-x[i+2]) * Math.sin(x[i+1]+x[i+2]) 00135 + 4.0 * x[i+1] - x[i] * Math.exp(x[i] - x[i+1]) - 3.0; 00136 00137 return true; 00138 } 00139 00140 @Override 00141 protected boolean eval_grad_f(int n, double[] x, boolean new_x, double[] grad_f) 00142 { 00143 grad_f[0] = 0.0; 00144 for( int i = 0; i < n-1; ++i ) 00145 { 00146 grad_f[i] += 400.0 * x[i] * (x[i] * x[i] - x[i+1]) + 2.0 * (x[i] - 1.0); 00147 grad_f[i+1] = -200.0 * (x[i] * x[i] - x[i+1]); 00148 } 00149 00150 return true; 00151 } 00152 00153 @Override 00154 protected boolean eval_jac_g(int n, double[] x, boolean new_x, int m, 00155 int nele_jac, int[] iRow, int[] jCol, double[] values) 00156 { 00157 if( values == null ) 00158 { 00159 // return the structure of the jacobian 00160 int ijac=0; 00161 for( int i = 0; i < n-2; ++i ) 00162 { 00163 iRow[ijac] = i; 00164 jCol[ijac] = i; 00165 ijac++; 00166 iRow[ijac] = i; 00167 jCol[ijac] = i+1; 00168 ijac++; 00169 iRow[ijac] = i; 00170 jCol[ijac] = i+2; 00171 ijac++; 00172 } 00173 } 00174 else 00175 { 00176 // return the values of the jacobian of the constraints 00177 int ijac=0; 00178 00179 for( int i = 0; i < n-2; ++i ) 00180 { 00181 // x[i] 00182 values[ijac] = -(1.0 + x[i]) * Math.exp(x[i] - x[i+1]); 00183 ijac++; 00184 // x[i+1] 00185 values[ijac] = 9.0 * x[i+1] * x[i+1] 00186 + Math.cos(x[i+1] - x[i+2]) * Math.sin(x[i+1] + x[i+2]) 00187 + Math.sin(x[i+1] - x[i+2]) * Math.cos(x[i+1] + x[i+2]) 00188 + 4.0 + x[i] * Math.exp(x[i] - x[i+1]); 00189 ijac++; 00190 // x[i+2] 00191 values[ijac] = 2.0 00192 - Math.cos(x[i+1] - x[i+2]) * Math.sin(x[i+1] + x[i+2]) 00193 + Math.sin(x[i+1] - x[i+2]) * Math.cos(x[i+1] + x[i+2]); 00194 ijac++; 00195 } 00196 } 00197 00198 return true; 00199 } 00200 00201 @Override 00202 protected boolean eval_h(int n, double[] x, boolean new_x, 00203 double obj_factor, int m, double[] lambda, boolean new_lambda, 00204 int nele_hess, int[] iRow, int[] jCol, double[] values) 00205 { 00206 if( values == null) 00207 { 00208 int ihes = 0; 00209 for( int i = 0; i < n; ++i ) 00210 { 00211 iRow[ihes] = i; 00212 jCol[ihes] = i; 00213 ++ihes; 00214 if( i < n-1 ) 00215 { 00216 iRow[ihes] = i; 00217 jCol[ihes] = i+1; 00218 ihes++; 00219 } 00220 } 00221 assert ihes == nele_hess; 00222 } 00223 else 00224 { 00225 int ihes = 0; 00226 for( int i = 0; i < n; ++i ) 00227 { 00228 // x[i],x[i] 00229 if( i < n-1 ) 00230 { 00231 values[ihes] = obj_factor * (2.0 + 400.0 * (3.0 * x[i] * x[i] - x[i+1])); 00232 if( i < n-2 ) 00233 values[ihes] -= lambda[i] * (2.0 + x[i]) * Math.exp(x[i] - x[i+1]); 00234 } 00235 else 00236 values[ihes] = 0.; 00237 00238 if( i > 0 ) 00239 { 00240 // x[i+1]x[i+1] 00241 values[ihes] += obj_factor * 200.0; 00242 if( i < n-1 ) 00243 values[ihes] += lambda[i-1]* (18.0 * x[i] 00244 - 2.0 * Math.sin(x[i] - x[i+1]) * Math.sin(x[i] + x[i+1]) 00245 + 2.0 * Math.cos(x[i] - x[i+1]) * Math.cos(x[i] + x[i+1]) 00246 - x[i-1] * Math.exp(x[i-1] - x[i])); 00247 } 00248 if( i > 1 ) 00249 // x[i+2]x[i+2] 00250 values[ihes] += lambda[i-2] * (-2.0 * Math.sin(x[i-1] - x[i]) * Math.sin(x[i-1] + x[i]) 00251 - 2.0 * Math.cos(x[i-1] - x[i]) * Math.cos(x[i-1] + x[i])); 00252 ihes++; 00253 00254 if( i < n-1 ) 00255 { 00256 // x[i],x[i+1] 00257 values[ihes] = obj_factor * (-400.0 * x[i]); 00258 if( i < n-2 ) 00259 values[ihes] += lambda[i]*(1.+x[i])*Math.exp(x[i]-x[i+1]); 00260 /* 00261 if (i>0) { 00262 // x[i+1],x[i+2] 00263 values[ihes] += 00264 lambda[i-1]*( sin(x[i]-x[i+1])*sin(x[i]+x[i+1]) 00265 + cos(x[i]-x[i+1])*cos(x[i]+x[i+1]) 00266 - cos(x[i]-x[i+1])*cos(x[i]+x[i+1]) 00267 - sin(x[i]-x[i+1])*sin(x[i]+x[i+1]) 00268 ); 00269 } 00270 */ 00271 ihes++; 00272 } 00273 } 00274 assert ihes == nele_hess; 00275 } 00276 00277 return true; 00278 } 00279 }