int variationalInequality_driver(VariationalInequality* problem, double *x, double *w, SolverOptions* options) { if (options == NULL) numerics_error("variationalInequality_driver", "null input for solver and/or global options"); assert(options->isSet); if (verbose > 0) solver_options_print(options); /* Solver name */ /*char * name = options->solverName;*/ int info = -1 ; /* Check for trivial case */ info = checkTrivialCase_vi(problem, x, w, options); if (info == 0){ double error; variationalInequality_computeError(problem, x , w, options->dparam[0], options, &error); printf("variationalInequality_driver. error = %8.4e\n", error); return info; } switch (options->solverId) { /* Non Smooth Gauss Seidel (NSGS) */ /* Extra Gradient algorithm */ case SICONOS_VI_EG: { numerics_printf_verbose(1, " ========================== Call ExtraGradient (EG) solver for VI problem ==========================\n"); variationalInequality_ExtraGradient(problem, x , w , &info , options); break; } case SICONOS_VI_FPP: { numerics_printf_verbose(1, " ========================== Call Fixed Point Projection (FPP) solver for VI problem ==========================\n"); variationalInequality_FixedPointProjection(problem, x , w , &info , options); break; } case SICONOS_VI_HP: { numerics_printf_verbose(1, " ========================== Call Hyperplane Projection (HP) solver for VI problem ==========================\n"); variationalInequality_HyperplaneProjection(problem, x , w , &info , options); break; } case SICONOS_VI_BOX_QI: { variationalInequality_box_newton_QiLSA(problem, x, w, &info, options); break; } case SICONOS_VI_BOX_AVI_LSA: { vi_box_AVI_LSA(problem, x, w, &info, options); break; } case SICONOS_VI_BOX_PATH: { vi_box_path(problem, x, w, &info, options); break; } default: { fprintf(stderr, "Numerics, variationalInequality_driver failed. Unknown solver.\n"); exit(EXIT_FAILURE); } } return info; }
void variationalInequality_ExtraGradient(VariationalInequality* problem, double *x, double *w, int* info, SolverOptions* options) { /* /\* int and double parameters *\/ */ int* iparam = options->iparam; double* dparam = options->dparam; /* Number of contacts */ int n = problem->size; /* Maximum number of iterations */ int itermax = iparam[0]; /* Tolerance */ double tolerance = dparam[0]; /***** Fixed point iterations *****/ int iter = 0; /* Current iteration number */ double error = 1.; /* Current error */ int hasNotConverged = 1; dparam[0] = dparam[2]; // set the tolerance for the local solver double * xtmp = (double *)malloc(n * sizeof(double)); double * wtmp = (double *)malloc(n * sizeof(double)); double rho = 0.0, rho_k =0.0; int isVariable = 0; if (dparam[3] > 0.0) { rho = dparam[3]; if (verbose > 0) { printf("----------------------------------- VI - Extra Gradient (EG) - Fixed stepsize with rho = %14.7e \n", rho); } } else { /* Variable step in iterations*/ isVariable = 1; rho = -dparam[3]; if (verbose > 0) { printf("----------------------------------- VI - Extra Gradient (EG) - Variable stepsize with starting rho = %14.7e \n", rho); } } /* Variable for Line_search */ int success =0; double error_k, light_error_sum =0.0; int ls_iter = 0; int ls_itermax = 10; double tau=dparam[4], tauinv=dparam[5], L= dparam[6], Lmin = dparam[7]; double a1=0.0, a2=0.0; double * x_k =0; double * w_k =0; if (isVariable) { x_k = (double *)malloc(n * sizeof(double)); w_k = (double *)malloc(n * sizeof(double)); } //isVariable=0; if (!isVariable) { /* double minusrho = -1.0*rho; */ while ((iter < itermax) && (hasNotConverged > 0)) { ++iter; /* xtmp <- x */ cblas_dcopy(n , x , 1 , xtmp, 1); /* wtmp <- F(xtmp) */ problem->F(problem, n, xtmp,wtmp); /* xtmp <- xtmp - F(xtmp) */ cblas_daxpy(n, -1.0, wtmp , 1, xtmp , 1) ; /* wtmp <- ProjectionOnX(xtmp) */ problem->ProjectionOnX(problem,xtmp,wtmp); /* x <- x - wtmp */ cblas_daxpy(n, -1.0, wtmp , 1, x , 1) ; /* x <- ProjectionOnX(x) */ cblas_dcopy(n , xtmp , 1 , x, 1); problem->ProjectionOnX(problem,xtmp,x); /* problem->F(problem,x,w); */ /* cblas_daxpy(n, -1.0, w , 1, x , 1) ; */ /* cblas_dcopy(n , x , 1 , xtmp, 1); */ /* problem->ProjectionOnX(problem,xtmp,x); */ /* **** Criterium convergence **** */ if (options->iparam[SICONOS_VI_ERROR_EVALUATION] == SICONOS_VI_ERROR_EVALUATION_FULL ) { variationalInequality_computeError(problem, x , w, tolerance, options, &error); } else if (options->iparam[SICONOS_VI_ERROR_EVALUATION] == SICONOS_VI_ERROR_EVALUATION_LIGHT ) { cblas_dcopy(n, xtmp, 1,x , 1) ; cblas_daxpy(n, -1.0, x_k , 1, xtmp , 1) ; light_error_sum = cblas_dnrm2(n,xtmp,1); double norm_x= cblas_dnrm2(n,x,1); if (fabs(norm_x) > DBL_EPSILON) light_error_sum /= norm_x; error=light_error_sum; } if (options->callback) { options->callback->collectStatsIteration(options->callback->env, n, x, w, error, NULL); } if (verbose > 0) { printf("----------------------------------- VI - Extra Gradient (EG) - Iteration %i rho = %14.7e \tError = %14.7e\n", iter, rho, error); } if (error < tolerance) hasNotConverged = 0; *info = hasNotConverged; } } if (isVariable) { if (iparam[1]==0)/* Armijo rule with Khotbotov ratio (default) */ { while ((iter < itermax) && (hasNotConverged > 0)) { ++iter; /* Store the error */ error_k = error; /* x_k <-- x store the x at the beginning of the iteration */ cblas_dcopy(n , x , 1 , x_k, 1); problem->F(problem, n, x, w_k); ls_iter = 0 ; success =0; rho_k=rho / tau; while (!success && (ls_iter < ls_itermax)) { /* if (iparam[3] && ls_iter !=0) rho_k = rho_k * tau * min(1.0,a2/(rho_k*a1)); */ /* else */ rho_k = rho_k * tau ; /* x <- x_k for the std approach*/ if (iparam[2]==0) cblas_dcopy(n, x_k, 1, x , 1) ; /* x <- x - rho_k* w_k */ cblas_daxpy(n, -rho_k, w_k , 1, x , 1) ; /* xtmp <- ProjectionOnX(x) */ problem->ProjectionOnX(problem,x,xtmp); problem->F(problem,n,xtmp,w); DEBUG_EXPR_WE( for (int i =0; i< 5 ; i++) { printf("xtmp[%i]=%12.8e\t",i,xtmp[i]); printf("w[%i]=F[%i]=%12.8e\n",i,i,w[i]);}); /* velocitytmp <- velocity */ /* cblas_dcopy(n, w, 1, wtmp , 1) ; */ /* velocity <- velocity - velocity_k */ cblas_daxpy(n, -1.0, w_k , 1, w , 1) ; /* a1 = ||w - w_k|| */ a1 = cblas_dnrm2(n, w, 1); DEBUG_PRINTF("a1 = %12.8e\n", a1); /* xtmp <- x */ cblas_dcopy(n, xtmp, 1,x , 1) ; /* xtmp <- x - x_k */ cblas_daxpy(n, -1.0, x_k , 1, xtmp , 1) ; /* a2 = || x - x_k || */ a2 = cblas_dnrm2(n, xtmp, 1) ; DEBUG_PRINTF("a2 = %12.8e\n", a2); DEBUG_PRINTF("test rho_k*a1 < L * a2 = %e < %e\n", rho_k*a1 , L * a2 ) ; success = (rho_k*a1 < L * a2)?1:0; /* printf("rho_k = %12.8e\t", rho_k); */ /* printf("a1 = %12.8e\t", a1); */ /* printf("a2 = %12.8e\t", a2); */ /* printf("norm x = %12.8e\t",cblas_dnrm2(n, x, 1) ); */ /* printf("success = %i\n", success); */ ls_iter++; } /* velocitytmp <- q */ /* cblas_dcopy(n , q , 1 , velocitytmp, 1); */ /* prodNumericsMatrix(n, n, alpha, M, reaction, beta, velocitytmp); */ problem->F(problem, n, x,wtmp); /* x <- x - rho_k* wtmp */ cblas_daxpy(n, -rho_k, wtmp , 1, x , 1) ; /* wtmp <- ProjectionOnX(xtmp) */ cblas_dcopy(n , x , 1 , xtmp, 1); problem->ProjectionOnX(problem,xtmp,x); DEBUG_EXPR_WE( for (int i =0; i< 5 ; i++) { printf("x[%i]=%12.8e\t",i,x[i]); printf("w[%i]=F[%i]=%12.8e\n",i,i,w[i]); } ); /* **** Criterium convergence **** */ if (options->iparam[SICONOS_VI_ERROR_EVALUATION] == SICONOS_VI_ERROR_EVALUATION_FULL ) { variationalInequality_computeError(problem, x , w, tolerance, options, &error); } else if (options->iparam[SICONOS_VI_ERROR_EVALUATION] == SICONOS_VI_ERROR_EVALUATION_LIGHT ) { cblas_dcopy(n, xtmp, 1,x , 1) ; cblas_daxpy(n, -1.0, x_k , 1, xtmp , 1) ; light_error_sum = cblas_dnrm2(n,xtmp,1); double norm_x= cblas_dnrm2(n,x,1); if (fabs(norm_x) > DBL_EPSILON) light_error_sum /= norm_x; error=light_error_sum; } DEBUG_PRINTF("error = %12.8e\t error_k = %12.8e\n",error,error_k); /*Update rho*/ if ((rho_k*a1 < Lmin * a2) && (error < error_k)) { rho =rho_k*tauinv; } else rho =rho_k; if (verbose > 0) { printf("----------------------------------- VI - Extra Gradient (EG) - Iteration %i rho = %14.7e \tError = %14.7e\n", iter, rho, error); } if (error < tolerance) hasNotConverged = 0; *info = hasNotConverged; } }// end iparam[1]==0
void variationalInequality_FixedPointProjection(VariationalInequality* problem, double *x, double *w, int* info, SolverOptions* options) { /* /\* int and double parameters *\/ */ int* iparam = options->iparam; double* dparam = options->dparam; /* Number of contacts */ int n = problem->size; /* Maximum number of iterations */ int itermax = iparam[0]; /* Tolerance */ double tolerance = dparam[0]; /***** Fixed point iterations *****/ int iter = 0; /* Current iteration number */ double error = 1.; /* Current error */ int hasNotConverged = 1; double * xtmp = (double *)malloc(n * sizeof(double)); double * wtmp = (double *)malloc(n * sizeof(double)); double rho = 0.0, rho_k =0.0; int isVariable = 0; if (dparam[3] > 0.0) { rho = dparam[3]; if (verbose > 0) { printf("----------------------------------- VI - Fixed Point Projection (FPP) - Fixed stepsize with rho = %14.7e \n", rho); } } else { /* Variable step in iterations*/ isVariable = 1; rho = -dparam[3]; if (verbose > 0) { printf("----------------------------------- VI - Fixed Point Projection (FPP) - Variable stepsize with starting rho = %14.7e \n", rho); } } /* Variable for Line_search */ int success =0; double error_k; int ls_iter = 0; int ls_itermax = 10; double tau=dparam[4], tauinv=dparam[5], L= dparam[6], Lmin = dparam[7]; DEBUG_PRINTF("tau=%g, tauinv=%g, L= %g, Lmin = %g",dparam[4], dparam[5], dparam[6], dparam[7] ) ; double a1=0.0, a2=0.0; double * x_k = NULL; double * w_k = NULL; if (isVariable) { x_k = (double *)malloc(n * sizeof(double)); w_k = (double *)malloc(n * sizeof(double)); } //isVariable=0; if (!isVariable) { /* double minusrho = -1.0*rho; */ while ((iter < itermax) && (hasNotConverged > 0)) { ++iter; problem->F(problem,n,x,w); cblas_daxpy(n, -1.0, w , 1, x , 1) ; cblas_dcopy(n , x , 1 , xtmp, 1); problem->ProjectionOnX(problem,xtmp,x); /* **** Criterium convergence **** */ variationalInequality_computeError(problem, x , w, tolerance, options, &error); if (options->callback) { options->callback->collectStatsIteration(options->callback->env, n, x, w, error, NULL); } if (verbose > 0) { printf("----------------------------------- VI - Fixed Point Projection (FPP) - Iteration %i rho = %14.7e \tError = %14.7e\n", iter, rho, error); } if (error < tolerance) hasNotConverged = 0; *info = hasNotConverged; } } else if (isVariable) { if (iparam[1]==0) /* Armijo rule with Khotbotov ratio (default) */ { DEBUG_PRINT("Variable step size method with Armijo rule with Khotbotov ratio (default) \n"); while ((iter < itermax) && (hasNotConverged > 0)) { ++iter; /* Store the error */ error_k = error; /* x_k <-- x store the x at the beginning of the iteration */ cblas_dcopy(n , x , 1 , x_k, 1); /* compute w_k =F(x_k) */ problem->F(problem,n,x,w_k); ls_iter = 0 ; success =0; rho_k=rho / tau; while (!success && (ls_iter < ls_itermax)) { /* if (iparam[3] && ls_iter !=0) rho_k = rho_k * tau * min(1.0,a2/(rho_k*a1)); */ /* else */ rho_k = rho_k * tau ; /* x <- x_k for the std approach*/ if (iparam[2]==0) cblas_dcopy(n, x_k, 1, x , 1) ; /* x <- x - rho_k* w_k */ cblas_daxpy(n, -rho_k, w_k , 1, x , 1) ; /* xtmp <- ProjectionOnX(x) */ problem->ProjectionOnX(problem,x,xtmp); problem->F(problem,n,xtmp,w); DEBUG_EXPR_WE( for (int i =0; i< 5 ; i++) { printf("xtmp[%i]=%12.8e\t",i,xtmp[i]); printf("w[%i]=F[%i]=%12.8e\n",i,i,w[i]);}); /* velocitytmp <- velocity */ /* cblas_dcopy(n, w, 1, wtmp , 1) ; */ /* velocity <- velocity - velocity_k */ cblas_daxpy(n, -1.0, w_k , 1, w , 1) ; /* a1 = ||w - w_k|| */ a1 = cblas_dnrm2(n, w, 1); DEBUG_PRINTF("a1 = %12.8e\n", a1); /* xtmp <- x */ cblas_dcopy(n, xtmp, 1,x , 1) ; /* xtmp <- x - x_k */ cblas_daxpy(n, -1.0, x_k , 1, xtmp , 1) ; /* a2 = || x - x_k || */ a2 = cblas_dnrm2(n, xtmp, 1) ; DEBUG_PRINTF("a2 = %12.8e\n", a2); DEBUG_PRINTF("test rho_k*a1 < L * a2 = %e < %e\n", rho_k*a1 , L * a2 ) ; success = (rho_k*a1 < L * a2)?1:0; /* printf("rho_k = %12.8e\t", rho_k); */ /* printf("a1 = %12.8e\t", a1); */ /* printf("a2 = %12.8e\t", a2); */ /* printf("norm x = %12.8e\t",cblas_dnrm2(n, x, 1) ); */ /* printf("success = %i\n", success); */ ls_iter++; } /* problem->F(problem,x,w); */ DEBUG_EXPR_WE( for (int i =0; i< 5 ; i++) { printf("x[%i]=%12.8e\t",i,x[i]); printf("w[%i]=F[%i]=%12.8e\n",i,i,w[i]);}); /* **** Criterium convergence **** */ variationalInequality_computeError(problem, x , w, tolerance, options, &error); DEBUG_EXPR_WE( if ((error < error_k)) { printf("(error < error_k) is satisfied\n"); }; );
void variationalInequality_HyperplaneProjection(VariationalInequality* problem, double *x, double *w, int* info, SolverOptions* options) { /* /\* int and double parameters *\/ */ int* iparam = options->iparam; double* dparam = options->dparam; /* Number of contacts */ int n = problem->size; /* Maximum number of iterations */ int itermax = iparam[0]; /* Maximum number of iterations in Line--search */ int lsitermax = iparam[1]; assert(lsitermax >0); /* Tolerance */ double tolerance = dparam[0]; /***** Fixed point iterations *****/ int iter = 0; /* Current iteration number */ double error = 1.; /* Current error */ int hasNotConverged = 1; dparam[0] = dparam[2]; // set the tolerance for the local solver double * xtmp = (double *)malloc(n * sizeof(double)); double * wtmp = (double *)malloc(n * sizeof(double)); double * xtmp2 = (double *)malloc(n * sizeof(double)); double * xtmp3 = (double *)malloc(n * sizeof(double)); int isVariable = 0; double tau = 1.0; double sigma = 0.99; if (dparam[3] > 0.0) { tau = dparam[3]; } else { printf("Hyperplane Projection method. tau <=0 is not well defined\n"); printf("Hyperplane Projection method. tau is set to 1.0\n"); } if (dparam[4] > 0.0 && dparam[4] < 1.0) { sigma = dparam[4]; } else { printf("Hyperplane Projection method. 0<sigma <1 is not well defined\n"); printf("Hyperplane Projection method. sigma is set to %6.4e\n", sigma); } isVariable=0; if (!isVariable) { /* double minusrho = -1.0*rho; */ while ((iter < itermax) && (hasNotConverged > 0)) { ++iter; /** xtmp <-- x (x_k) */ cblas_dcopy(n , x , 1 , xtmp, 1); /* xtmp (y_k)= P_X(x_k-tau F(x_k)) */ problem->F(problem, n, xtmp, wtmp); cblas_daxpy(n, -tau, wtmp , 1, xtmp , 1) ; cblas_dcopy(n , xtmp, 1 , xtmp2, 1); problem->ProjectionOnX(problem, xtmp2,xtmp); // Armijo line search int stopingcriteria = 1; int ls_iter = -1; double alpha = 1.0; double lhs = NAN; double rhs; // xtmp3 = z_k-y_k cblas_dcopy(n , x , 1 , xtmp3, 1); cblas_daxpy(n, -1.0, xtmp, 1, xtmp3, 1); rhs = cblas_dnrm2(n,xtmp3, 1); rhs = sigma / tau * rhs * rhs; DEBUG_EXPR_WE( for (int i =0; i< n ; i++) { printf("(y_k) xtmp[%i]=%6.4e\t",i,xtmp[i]); printf("(x_k-y_k) xtmp3[%i]=%6.4e\n",i,xtmp3[i]); } ); while (stopingcriteria && (ls_iter < lsitermax)) { ls_iter++ ; /* xtmp2 = alpha * y_k + (1-alpha) x_k */ alpha = 1.0 / (pow(2.0, ls_iter)); DEBUG_PRINTF("alpha = %6.4e\n", alpha); cblas_dcopy(n ,xtmp , 1 , xtmp2, 1); cblas_dscal(n , alpha, xtmp2, 1); cblas_daxpy(n, 1.0-alpha, x, 1, xtmp2, 1); /* wtmp = */ problem->F(problem, n, xtmp2,wtmp); DEBUG_EXPR_WE( for (int i =0; i< n ; i++) { printf("(z_k) xtmp2[%i]=%6.4e\n",i,xtmp2[i]); printf("F(z_k) wtmp[%i]=%6.4e\n",i,wtmp[i]); } ); lhs = cblas_ddot(n, wtmp, 1, xtmp3, 1); if (lhs >= rhs) stopingcriteria = 0; DEBUG_PRINTF("ls_iter= %i, lsitermax =%i, stopingcriteria %i\n",ls_iter,lsitermax,stopingcriteria); DEBUG_PRINTF("Number of iteration in Armijo line search = %i\t, lhs = %6.4e\t, rhs = %6.4e\t, alpha = %6.4e\t, sigma = %6.4e\t, tau = %6.4e\n", ls_iter, lhs, rhs, alpha, sigma, tau); } cblas_dcopy(n , x , 1 , xtmp3, 1); cblas_daxpy(n, -1.0, xtmp2, 1, xtmp3, 1); DEBUG_PRINTF("norm(x-x_k) = %6.4e\n",cblas_dnrm2(n, xtmp3, 1) ); lhs=cblas_ddot(n, wtmp, 1, xtmp3, 1); double nonorm = cblas_dnrm2(n, wtmp, 1); double rhoequiv = lhs / (nonorm * nonorm); /* rhoequiv =1.0; */ DEBUG_PRINTF("nonorm = %6.4e\n", nonorm); DEBUG_PRINTF("lhs = %6.4e\n", lhs); DEBUG_PRINTF("rho equiv = %6.4e\n", rhoequiv); cblas_daxpy(n, -rhoequiv, wtmp, 1, x , 1); cblas_dcopy(n , x, 1 , xtmp, 1); problem->ProjectionOnX(problem, xtmp,x); /* **** Criterium convergence **** */ variationalInequality_computeError(problem, x , w, tolerance, options, &error); DEBUG_EXPR_WE( for (int i =0; i< n ; i++) { printf("x[%i]=%6.4e\t",i,x[i]); printf("w[%i]=F[%i]=%6.4e\n",i,i,w[i]); } );