static int32 ipopt_eligible_solver(slv_system_t server){ struct rel_relation **rp; struct var_variable **vp; rel_filter_t rfilt; var_filter_t vfilt; rfilt.matchbits = (REL_CONDITIONAL | REL_INWHEN); rfilt.matchvalue = (REL_CONDITIONAL | REL_INWHEN); vfilt.matchbits = (VAR_BINARY); vfilt.matchvalue = (VAR_BINARY); /// @todo check that there is a MAXIMIZE or MINIMIZE statement if (slv_get_obj_relation(server) == NULL) ERROR_REPORTER_HERE(ASC_USER_ERROR,"No objective function found"); /// @todo check that there are no WHENs or CONDITIONALs for( rp=slv_get_solvers_rel_list(server); *rp != NULL ; ++rp ) { if(rel_apply_filter(*rp,&rfilt)){ ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"WHEN and CONDITIONAL Statements are not supported."); return(FALSE); } } /// @todo check that there are no discrete-valued variables for( vp=slv_get_solvers_var_list(server); *vp != NULL ; ++vp ) { if(var_apply_filter(*vp,&vfilt)){ ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Discrete Variables not supported."); return(FALSE); } } /// @todo check anything else? return 1; }
static SlvClientToken ipopt_create(slv_system_t server, int32 *statusindex){ IpoptSystem *sys; sys = ASC_NEW_CLEAR(IpoptSystem); if(sys==NULL){ *statusindex = 1; return sys; } sys->p.parms = sys->pa; sys->p.dynamic_parms = 0; ipopt_get_default_parameters(server,(SlvClientToken)sys,&(sys->p)); sys->p.whose = (*statusindex); sys->presolved = 0; sys->resolve = 0; sys->n = -1; sys->m = -1; sys->s.ok = TRUE; sys->s.calc_ok = TRUE; sys->s.costsize = 0; sys->s.cost = NULL; /*redundant, but sanity preserving */ sys->s.block.number_of = 1; sys->s.block.current_block = 0; sys->s.block.current_reordered_block = 0; sys->s.block.current_size = 0; sys->s.block.previous_total_size = 0; sys->s.block.iteration = 0; sys->s.block.funcs = 0; sys->s.block.jacs = 0; sys->s.block.cpu_elapsed = 0; sys->s.block.functime = 0; sys->s.block.jactime = 0; sys->s.block.residual = 0; sys->rfilt.matchbits = (REL_INCLUDED | REL_ACTIVE); sys->rfilt.matchvalue = (REL_INCLUDED | REL_ACTIVE); sys->vfilt.matchbits = (VAR_ACTIVE | VAR_INCIDENT | VAR_SVAR | VAR_FIXED); sys->vfilt.matchvalue = (VAR_ACTIVE | VAR_INCIDENT | VAR_SVAR); sys->vlist = slv_get_solvers_var_list(server); sys->rlist = slv_get_solvers_rel_list(server); sys->rtot = slv_get_num_solvers_rels(server); sys->vtot = slv_get_num_solvers_vars(server); sys->obj = slv_get_obj_relation(server); sys->slv = server; /*char *tmp = rel_make_name(sys->slv,sys->obj); //CONSOLE_DEBUG("Objective relation is '%s'",tmp); ASC_FREE(tmp);*/ //CONSOLE_DEBUG("There are %d constraint relations.", sys->rtot); if(sys->vlist == NULL) { ASC_FREE(sys); ERROR_REPORTER_HERE(ASC_PROG_ERR,"IPOPT called with no variables."); *statusindex = -2; return NULL; } if(sys->rlist == NULL && sys->obj == NULL) { ASC_FREE(sys); ERROR_REPORTER_HERE(ASC_PROG_ERR,"IPOPT called with no relations or objective."); *statusindex = -1; return NULL; } /* do nothing with the objective list, pars, bounds, extrels, etc etc */ slv_check_var_initialization(server); *statusindex = 0; return((SlvClientToken)sys); }
//------------------------------------------------------------------------- void Prg_ASCEND::setup() { int n, me, m; int i, j, row_idx, idx; SPMAT *J; int nincidences; const struct var_variable **incidences; // obtain ASCEND system // todo: should check that system can be solved with HQP (e.g. no integers) _nvars = slv_get_num_solvers_vars(_slv_system); _vars = slv_get_solvers_var_list(_slv_system); _nrels = slv_get_num_solvers_rels(_slv_system); _rels = slv_get_solvers_rel_list(_slv_system); _obj = slv_get_obj_relation(_slv_system); // count number of optimization variables and bounds _var_lb = v_resize(_var_lb, _nvars); _var_ub = v_resize(_var_ub, _nvars); _var_asc2hqp = iv_resize(_var_asc2hqp, _nvars); _derivatives = v_resize(_derivatives, _nvars); _var_master_idxs = iv_resize(_var_master_idxs, _nvars); _var_solver_idxs = iv_resize(_var_solver_idxs, _nvars); n = 0; me = 0; m = 0; for (i = 0; i < _nvars; i++) { _var_lb[i] = var_lower_bound(_vars[i]); _var_ub[i] = var_upper_bound(_vars[i]); /* var_write_name(_slv_system, _vars[i], stderr); fprintf(stderr, ":\t%i,\t%g,\t%g\n", var_fixed(_vars[i]), _var_lb[i], _var_ub[i]); */ if (var_fixed(_vars[i])) { _var_asc2hqp[i] = -1; } else { _var_asc2hqp[i] = n++; if (_var_lb[i] == _var_ub[i]) ++me; else { if (_var_lb[i] > -_Inf) ++m; if (_var_ub[i] < _Inf) ++m; } } } // consider bounds as linear constraints (i.e. no Jacobian update) _me_bounds = me; _m_bounds = m; // count number of HQP constraints for (i = 0; i < _nrels; i++) { if (rel_equal(_rels[i])) ++me; // equality constraint else ++m; // inequality constraint } // allocate QP approximation and optimization variables vector _qp->resize(n, me, m); _x = v_resize(_x, n); // allocate sparse structure for bounds // (write constant elements in Jacobians) me = m = 0; for (i = 0; i < _nvars; i++) { idx = _var_asc2hqp[i]; if (idx < 0) continue; if (_var_lb[i] == _var_ub[i]) { row_idx = me++; sp_set_val(_qp->A, row_idx, idx, 1.0); } else { if (_var_lb[i] > -_Inf) { row_idx = m++; sp_set_val(_qp->C, row_idx, idx, 1.0); } if (_var_ub[i] < _Inf) { row_idx = m++; sp_set_val(_qp->C, row_idx, idx, -1.0); } } } // allocate sparse structure for general constraints // (just insert dummy values; actual values are set in update method) for (i = 0; i < _nrels; i++) { if (rel_equal(_rels[i])) { row_idx = me++; J = _qp->A; } else { row_idx = m++; J = _qp->C; } nincidences = rel_n_incidences(_rels[i]); incidences = rel_incidence_list(_rels[i]); for (j = 0; j < nincidences; j++) { idx = _var_asc2hqp[var_sindex(incidences[j])]; if (idx >= 0) sp_set_val(J, row_idx, idx, 1.0); } } // todo: setup sparse structure of Hessian // for now initialize something resulting in dense BFGS update for (j = 0; j < n-1; j++) { sp_set_val(_qp->Q, j, j, 0.0); sp_set_val(_qp->Q, j, j+1, 0.0); } sp_set_val(_qp->Q, j, j, 0.0); }