bool LpSolve::solve() { set_add_rowmode(lp, TRUE); for (size_t c = 0; c < moduleIndexMap.size(); ++c) { colno[c] = c + 1; set_binary(lp, c + 1, TRUE); } for (auto &equation : equations) { memset(row, 0, moduleIndexMap.size() * sizeof(*row)); for (auto const &module : equation->getModules()) { row[moduleIndexMap.at(module->toString())] = 1; } add_constraintex(lp, moduleIndexMap.size(), row, colno, equation->getIsEqualityConstraint() ? EQ : LE, 1); } set_add_rowmode(lp, FALSE); memset(row, 0, moduleIndexMap.size() * sizeof(*row)); set_obj_fnex(lp, moduleIndexMap.size(), row, colno); if (::solve(lp) != OPTIMAL) { return false; } get_variables(lp, row); for (size_t j = 0; j < moduleIndexMap.size(); j++) printf("%s: %f\n", get_col_name(lp, j + 1), row[j]); return true; }
ErrorCode ReadNC::read_header() { dbgOut.tprint(1, "Reading header...\n"); // Get the global attributes int numgatts; int success; success = NCFUNC(inq_natts )(fileId, &numgatts); if (success) MB_SET_ERR(MB_FAILURE, "Couldn't get number of global attributes"); // Read attributes into globalAtts ErrorCode result = get_attributes(NC_GLOBAL, numgatts, globalAtts);MB_CHK_SET_ERR(result, "Trouble getting global attributes"); dbgOut.tprintf(1, "Read %u attributes\n", (unsigned int) globalAtts.size()); // Read in dimensions into dimNames and dimLens result = get_dimensions(fileId, dimNames, dimLens);MB_CHK_SET_ERR(result, "Trouble getting dimensions"); dbgOut.tprintf(1, "Read %u dimensions\n", (unsigned int) dimNames.size()); // Read in variables into varInfo result = get_variables();MB_CHK_SET_ERR(result, "Trouble getting variables"); dbgOut.tprintf(1, "Read %u variables\n", (unsigned int) varInfo.size()); return MB_SUCCESS; }
/* * add new watch */ variable* add_watch(gchar* expression) { gchar command[1000]; variable *var = variable_new(expression, VT_WATCH); watches = g_list_append(watches, var); /* try to create a variable */ gchar *record = NULL; gchar *escaped = g_strescape(expression, NULL); sprintf(command, "-var-create - * \"%s\"", escaped); g_free(escaped); if (RC_DONE != exec_sync_command(command, TRUE, &record)) { g_free(record); return var; } gchar *pos = strstr(record, "name=\"") + strlen("name=\""); *strchr(pos, '\"') = '\0'; g_string_assign(var->internal, pos); var->evaluated = TRUE; GList *vars = g_list_append(NULL, var); get_variables(vars); g_free(record); g_list_free(vars); return var; }
/// Generates the truth table. void MainWindow::generate() { delete_columns(); get_variables(); FunctionParser p; switch(m_mode) { case Function: char func[128]; Edit_GetText(m_hWndFunction, func, 128); try { p = FunctionParser(m_variables, func); } catch(FunctionParser::FunctionParserException& e) { MessageBox(e.what(), "Function Parser Error", MB_OK | MB_ICONERROR); return; } build_table(&p); break; case Minterm: break; case Maxterm: break; } }
void lock_hierarchy::handleError(const char *what, std::size_t lock_level, const void *theLock) { variables_t &variables = get_variables(); std::cerr << "locking hierarchy error: " << what << " lock_level=" << lock_level << " theLock=" << theLock << std::endl; std::cerr << "locked levels:\n"; std::size_t lastV = 0, count = 0; const std::size_t skipAtCount = 3; for(std::size_t v : variables.lock_levels) { if(count == 0 || lastV != v) { if(count > skipAtCount) { std::cerr << "(" << count - skipAtCount << " not shown)\n"; } lastV = v; count = 1; } else { count++; } if(count <= skipAtCount) std::cerr << v << "\n"; } if(count > skipAtCount) { std::cerr << "(" << count - skipAtCount << " not shown)\n"; } std::cerr << std::endl; std::terminate(); }
Solution LpsolveAdaptator::getSolution(lprec * lp) { Solution sol = Solution(); REAL row[get_Norig_columns(lp)]; #ifdef DEBUG set_verbose(lp, NORMAL); write_LP(lp, stdout); #else set_verbose(lp, CRITICAL); #endif solve(lp); // WARNING possible conversion failure from double to float sol.setZ(get_objective(lp)); get_variables(lp, row); #ifdef DEBUG for(int j = 0; j < get_Norig_columns(lp); j++) { printf("%s: %f\n", get_col_name(lp, j + 1), row[j]); } #endif for (int i = 0; i < get_Norig_columns(lp); i++) { double var_value = (double)row[i]; sol.addVariable(var_value); } delete_lp(lp); return sol; }
/* * get list of children */ GList* get_children (gchar* path) { GList *children = NULL; gchar command[1000]; result_class rc; gchar *record = NULL; gchar *pos = NULL; /* children number */ sprintf(command, "-var-info-num-children \"%s\"", path); rc = exec_sync_command(command, TRUE, &record); if (RC_DONE != rc) return NULL; pos = strstr(record, "numchild=\"") + strlen("numchild=\""); *(strchr(pos, '\"')) = '\0'; int numchild = atoi(pos); g_free(record); if (!numchild) return NULL; /* recursive get children and put into list */ sprintf(command, "-var-list-children \"%s\"", path); rc = exec_sync_command(command, TRUE, &record); if (RC_DONE == rc) { pos = record; while ( (pos = strstr(pos, "child={")) ) { gchar *name, *internal; /* name */ pos = strstr(pos, "name=\"") + strlen("name=\""); *(strstr(pos, "\",exp=\"")) = '\0'; internal = pos; pos += strlen(pos) + 1; /* exp */ pos = strstr(pos, "exp=\"") + strlen("exp=\""); *(strstr(pos, "\",numchild=\"")) = '\0'; name = g_strcompress(pos); variable *var = variable_new2(name, internal, VT_CHILD); var->evaluated = TRUE; pos += strlen(pos) + 1; children = g_list_prepend(children, var); g_free(name); } } g_free(record); get_variables(children); return children; }
bool CFeasibilityMap::SolveLP(Matrix &A, ColumnVector &b, ColumnVector &x) { lprec *lp ; int n_row = A.nrows(); int n_col = A.ncols(); x = ColumnVector(n_col); x = 0; lp = make_lp(0,n_col) ; double *input_row = new double[1+n_col]; for (int i_row=1; i_row<=n_row; i_row++){ input_row[0] = 0 ; // The first zero is for matrix form for (int j=1; j<=n_col; j++){ input_row[j] = A(i_row,j) ; } add_constraint(lp, input_row, LE, b(i_row)) ; } delete [] input_row; double *input_obj = new double[1+n_col]; // The first zero is for matrix form input_obj[0] = 0 ; for (int j=1; j<=n_col; j++){ input_obj[j] = 1 ; } set_obj_fn(lp, input_obj) ; delete [] input_obj; set_verbose(lp, IMPORTANT); // NEUTRAL (0), IMPORTANT (3), NORMAL (4), FULL (6) bool is_feasible = (solve(lp)==0); // 0: feasible solution found, 2: not found // solution for minimizing objective function double* x_min = new double[n_col]; double* x_max = new double[n_col]; if (is_feasible) { get_variables(lp, x_min); set_maxim(lp); is_feasible = (solve(lp)==0); // 0: feasible solution found, 2: not found if (is_feasible) { get_variables(lp, x_max); for (int i = 0; i < n_col; i++) { x(i+1) = (x_min[i] + x_max[i]) / 2.0; } } } delete [] x_min; delete [] x_max; delete_lp(lp); return is_feasible; }
/** \brief Perform backtraking linesearch. * */ double backtracking_linesearch(problem_data_t *pdat, variables_t *vars, double t, double *Adw, double *xnew) { int i, m, n; double phi, s; double *vnew, *wnew, *unew; dmatrix *matX1, *matX2; double *g, *h, *z, *expz, *expmz, *ac, *ar, *b, *d1, *d2, *Aw; double *x, *v, *w, *u, *dx, *dv, *dw, *du, *gv, *gw, *gu, *gx; double lambda, gdx; get_problem_data(pdat, &matX1, &matX2, &ac, &ar, &b, &lambda); m = matX1->m; n = matX1->n; get_variables(vars, &x, &v, &w, &u, &dx, &dv, &dw, &du, &gx, &gv, &gw, &gu, &g, &h, &z, &expz, &expmz, &d1, &d2, &Aw); vnew = xnew; wnew = xnew+1; unew = xnew+1+n; s = 1.0; phi = eval_phi(m, n, z, expz, expmz, w, u, lambda, t); dmat_yAmpqx(matX1, ac, ar, dw, Adw); /* see below */ dmat_waxpby(m, dv[0], b, 1, Adw, Adw); /* Adw := A*dw+b*dv */ dmat_waxpby(m, v[0], b, 1, Aw, Aw); /* Aw := A*w+b*v */ dmat_waxpby(n+n+1, 1, dx, 1, x, xnew); /* xnew:= x + dx */ gdx = dmat_dot(n+n+1, gx, dx); for (i = 1; i <= MAX_LS_ITER; i++) { /* x := x + s*dx */ if (is_indomain(wnew, unew, n) == TRUE) { double newphi; /* z = A*(w+s*dw) + b*(v+s*dw) = (Aw+bv) + s*(Adw+bdv), where Aw, Adw+bdv are vectors. */ dmat_waxpby(m, s, Adw, 1, Aw, z); dmat_yexpx(m, z, expz); dmat_yinvx(m, expz, expmz); newphi = eval_phi(m, n, z, expz, expmz, wnew, unew, lambda, t); if (newphi <= phi + ALPHA * s * gdx) break; } s *= BETA; dmat_waxpby(n+n+1, s, dx, 1, x, xnew); } if (i > MAX_LS_ITER) return -1; dmat_vcopy(n+n+1,xnew,x); return s; }
int LoadBalancing::lp_solve_model() { //Returns 0 when an optimal solution is found, //returns 1 if the solution is suboptimal due to an overlap constraint, and we should use fewer nodes //returns 2 when a suboptimal solution is found (solver timed out) //returns 3 if another error occurred int ret; int Ncol=3*num_using_nodes_+(num_using_nodes_-1)*(num_quantiles_+2); REAL *vars = (REAL*)malloc(Ncol*sizeof(REAL)); set_verbose(lp, IMPORTANT); set_timeout(lp, solver_timeout_); default_basis(lp); ret = solve(lp); if(ret==1){ fprintf(stderr, "lp_solve: Suboptimal solution (solver timed out)\n"); return 2; } if(ret!=0 && ret!=1){ fprintf(stderr, "lp_solve: Solution not found\n"); return 3; } print_solution(lp, 3); get_variables(lp, vars); //Cutvector: optimal_cutvector_.resize(num_using_nodes_); for(int i=0;i<num_using_nodes_;i++){ optimal_cutvector_.at(i)=round(width_*vars[i]); } //Estimated completion time: est_completion_time_=(float)vars[num_using_nodes_]; /* printf("\nOptimal cutvector:\n"); for(int i=0;i<num_using_nodes_;i++){ printf("%d\n", optimal_cutvector_.at(i)); } printf("Estimated completion time: %f\n", est_completion_time_); */ //If the first cut is 0, that would be an indication that the cutvector we obtained is suboptimal, //due to the overlap constraint. //We should most likely use fewer nodes. if(optimal_cutvector_.front()==0){ fprintf(stderr, "lp_solve: Suboptimal solution (first cut was 0), we should use fewer processing nodes\n"); return 1; } free(vars); return ret; }
long __declspec(dllexport) WINAPI _get_variables(lprec *lp, double *variables) { long ret; if (lp != NULL) { freebuferror(); ret = get_variables(lp, variables); } else ret = 0; return(ret); }
static int get_terms_object(SEXP factors, SEXP variables, struct design *s, struct design *r, struct design2 *d, struct terms_object *tm) { int err = 0; err = get_variables(variables, s, r, d, &tm->variables); if (err < 0) goto out; err = get_terms(factors, &tm->variables, s, r, d, &tm->terms); if (err < 0) goto out; out: return err; }
int truth_table(char ipstr[], int fnvalues[], int *no_of_variables){ int i, j, output, len; remove_spaces(ipstr); if(check_for_valid_characters(ipstr)){ printf("ERROR! Use only valid characters - ~&|() a-z A-Z\n"); return 1; } set_precedence(precedence, ipstr); get_variables(listvar, &numvar, precedence); if(conv_to_postfix(ipstr, opstr, precedence) == 1){ printf("\nError in input\n"); return 1; } len = strlen(ipstr); /* Truth-table Printing */ printf("\n"); for(i=0; i<numvar; i++){ printf("%c ", listvar[i]); } printf("%s ", ipstr); for(i=0; i<(1<<numvar); i++){ /* For each permutation of bits */ printf("\n"); compute_val_var_from_perm(i, valvar, numvar); for(j=0; j<numvar; j++) printf("%d ", valvar[j]); output = eval_postfix(opstr, valvar, numvar, listvar); if(output == 1){ printf("Error : eval - not enuff operands\n"); return 1; } fnvalues[i] = output - '0'; printf("%*c ", len/2 + 1, output); } *no_of_variables = numvar; printf("\n"); return 0; }
void testVarParser(char *buf) { printf("===== Testing Variable parser ======\n"); // time_t start = GetTickCount(); VariableList li; // fflush(stdout); std::map<std::string, std::string> ignoreTokens; get_variables(buf, li, ignoreTokens, true); // time_t end = GetTickCount(); for (VariableList::iterator iter = li.begin(); iter != li.end(); iter++) { Variable var = *iter; var.Print(); } // printf("total time: %d\n", end-start); printf("matches found: %d\n", li.size()); }
struct svalue * debug_command(char *debcmd, int argc, struct svalue *argv) { static struct svalue retval; int dbnum, dbi, il; char buff[200]; for (dbi = -1, dbnum = 0; debc[dbnum]; dbnum++) { if (strcmp(debcmd, debc[dbnum]) == 0) dbi = dbnum; } if (dbi < 0) { retval.type = T_NUMBER; retval.u.number = 0; return &retval; } switch (dbi) { case 0: /* index */ retval.type = T_POINTER; retval.u.vec = allocate_array(dbnum); for (il = 0; il < dbnum; il++) { retval.u.vec->item[il].type = T_STRING; retval.u.vec->item[il].string_type = STRING_CSTRING; retval.u.vec->item[il].u.string = debc[il]; } return &retval; case 1: /* malloc */ retval.type = T_STRING; retval.string_type = STRING_MSTRING; retval.u.string = make_mstring((char *)dump_malloc_data()); return &retval; case 2: /* status */ case 3: /* status tables */ retval.type = T_STRING; retval.string_type = STRING_MSTRING; retval.u.string = (char *)get_gamedriver_info(debc[dbi]); return &retval; case 4: /* mudstatus on/off eval_lim time_lim */ if (argc < 3 || argv[0].type != T_STRING || argv[1].type != T_NUMBER || argv[2].type != T_NUMBER) break; if (strcmp(argv[0].u.string, "on") == 0) mudstatus_set(1, argv[1].u.number, argv[2].u.number); else if (strcmp(argv[0].u.string, "off") == 0) mudstatus_set(0, argv[1].u.number, argv[2].u.number); else break; retval.type = T_NUMBER; retval.u.number = 1; return &retval; case 5: /* functionlist object */ if (argc < 1 || argv[0].type != T_OBJECT) break; retval.type = T_POINTER; retval.u.vec = allocate_array(argv[0].u.ob->prog->num_functions); for (il = 0; il < (int)argv[0].u.ob->prog->num_functions; il++) { retval.u.vec->item[il].type = T_STRING; retval.u.vec->item[il].string_type = STRING_SSTRING; retval.u.vec->item[il].u.string = reference_sstring(argv[0].u.ob->prog->functions[il].name); } return &retval; case 6: /* rusage */ { #ifdef RUSAGE /* Only defined if we compile GD with RUSAGE */ char buff[500]; struct rusage rus; long utime, stime; long maxrss; if (getrusage(RUSAGE_SELF, &rus) < 0) buff[0] = 0; else { utime = rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000; stime = rus.ru_stime.tv_sec * 1000 + rus.ru_stime.tv_usec / 1000; maxrss = rus.ru_maxrss; (void)sprintf(buff, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", utime, stime, maxrss, rus.ru_ixrss, rus.ru_idrss, rus.ru_isrss, rus.ru_minflt, rus.ru_majflt, rus.ru_nswap, rus.ru_inblock, rus.ru_oublock, rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals, rus.ru_nvcsw, rus.ru_nivcsw); } retval.type = T_STRING; retval.string_type = STRING_MSTRING; retval.u.string = make_mstring(buff); return &retval; #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with RUSAGE flag.\n"; return &retval; #endif } #if defined(PROFILE_LPC) case 7: /* top_ten_cpu */ { #define NUMBER_OF_TOP_TEN 100 struct program *p[NUMBER_OF_TOP_TEN]; struct vector *v; struct program *prog; int i, j; for(i = 0; i < NUMBER_OF_TOP_TEN; i++) p[i] = (struct program *)0L; prog = prog_list; do { for(i = NUMBER_OF_TOP_TEN-1; i >= 0; i--) { if ( p[i] && (prog->cpu <= p[i]->cpu)) break; } if (i < (NUMBER_OF_TOP_TEN - 1)) for (j = 0; j <= i; j++) if (strcmp(p[j]->name,prog->name) == 0) { i = NUMBER_OF_TOP_TEN-1; break; } if (i < (NUMBER_OF_TOP_TEN - 1)) { j = NUMBER_OF_TOP_TEN - 2; while(j > i) { p[j + 1] = p[j]; j--; } p[i + 1] = prog; } } while (prog_list != (prog = prog->next_all)); v = make_cpu_array(NUMBER_OF_TOP_TEN, p); if (v) { retval.type = T_POINTER; retval.u.vec = v; return &retval; } break; #undef NUMBER_OF_TOP_TEN } #else case 7: retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with PROFILE_LPC flag.\n"; return &retval; #endif case 8: /* object_cpu object */ { long long c_num; if (argc && (argv[0].type == T_OBJECT)) { #if defined(PROFILE_LPC) c_num = argv[0].u.ob->prog->cpu * 1e6; #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with PROFILE_LPC flag.\n"; return &retval; #endif } else { #ifdef RUSAGE struct rusage rus; if (getrusage(RUSAGE_SELF, &rus) < 0) { c_num = -1; } else { c_num = (long long)rus.ru_utime.tv_sec * 1000000 + rus.ru_utime.tv_usec + (long long)rus.ru_stime.tv_sec * 1000000 + rus.ru_stime.tv_usec; } #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with RUSAGE flag.\n"; return &retval; #endif } retval.type = T_NUMBER; retval.u.number = c_num; return &retval; } case 9: /* swap, object */ #if 0 /* can not swap while executing */ if (argc && (argv[0].type == T_OBJECT)) (void)swap(argv[0].u.ob); #endif retval = const1; return &retval; case 10: /* version, */ { char buff[64]; (void)snprintf(buff, sizeof(buff), "%6.6s%02d %s %s", GAME_VERSION, PATCH_LEVEL, __DATE__, __TIME__); retval.type = T_STRING; retval.string_type = STRING_MSTRING; retval.u.string = make_mstring(buff); return &retval; } case 11: /* wizlist, wizname */ /* * Prints information, will be changed */ retval = const1; return &retval; case 12: /* trace, bitmask */ { int ot = -1; extern struct object *current_interactive; if (current_interactive && current_interactive->interactive) { if (argc && (argv[0].type == T_NUMBER)) { ot = current_interactive->interactive->trace_level; current_interactive->interactive->trace_level = argv[0].u.number; } } retval.type = T_NUMBER; retval.u.number = ot; return &retval; } case 13: /* traceprefix, pathstart */ { char *old = 0; extern struct object *current_interactive; if (current_interactive && current_interactive->interactive) { if (argc) { old = current_interactive->interactive->trace_prefix; if (argv[0].type == T_STRING) { current_interactive->interactive->trace_prefix = make_sstring(argv[0].u.string); } else current_interactive->interactive->trace_prefix = 0; } } if (old) { retval.type = T_STRING; retval.string_type = STRING_SSTRING; retval.u.string = old; } else retval = const0; return &retval; } case 14: /* call_out_info, */ { extern struct vector *get_calls(struct object *); if (argv[0].type != T_OBJECT) break; retval.type = T_POINTER; retval.u.vec = get_calls(argv[0].u.ob); return &retval; } case 15: /* inherit_list, object */ if (argc && (argv[0].type == T_OBJECT)) { retval.type = T_POINTER; retval.u.vec = inherit_list(argv[0].u.ob); return &retval; } else { retval = const0; return &retval; } case 16: /* load_average, */ retval.type = T_STRING; retval.string_type = STRING_MSTRING; retval.u.string = make_mstring(query_load_av()); return &retval; case 17: /* shutdown, */ startshutdowngame(0); retval = const1; return &retval; case 18: /* "object_info", num object */ { struct object *ob; char db_buff[1024], tdb[200]; int i; if (argc < 2 || argv[0].type != T_NUMBER || argv[1].type != T_OBJECT) break; if (argv[0].u.number == 0) { int flags; struct object *obj2; if ( argv[1].type != T_OBJECT) break; ob = argv[1].u.ob; flags = ob->flags; (void)sprintf(db_buff,"O_ENABLE_COMMANDS : %s\nO_CLONE : %s\nO_DESTRUCTED : %s\nO_SWAPPED : %s\nO_ONCE_INTERACTIVE: %s\nO_CREATED : %s\n", flags&O_ENABLE_COMMANDS ?"TRUE":"FALSE", flags&O_CLONE ?"TRUE":"FALSE", flags&O_DESTRUCTED ?"TRUE":"FALSE", flags&O_SWAPPED ?"TRUE":"FALSE", flags&O_ONCE_INTERACTIVE?"TRUE":"FALSE", flags&O_CREATED ?"TRUE":"FALSE"); (void)sprintf(tdb,"time_of_ref : %d\n", ob->time_of_ref); (void)strcat(db_buff, tdb); (void)sprintf(tdb,"ref : %d\n", ob->ref); (void)strcat(db_buff, tdb); #ifdef DEBUG (void)sprintf(tdb,"extra_ref : %d\n", ob->extra_ref); (void)strcat(db_buff, tdb); #endif (void)sprintf(tdb,"swap_num : %d\n", ob->swap_num); (void)strcat(db_buff, tdb); (void)snprintf(tdb, sizeof(tdb), "name : '%s'\n", ob->name); (void)strcat(db_buff, tdb); (void)snprintf(tdb, sizeof(tdb), "next_all : OBJ(%s)\n", ob->next_all?ob->next_all->name: "NULL"); (void)strcat(db_buff, tdb); if (obj_list == ob) { (void)strcat(db_buff, "This object is the head of the object list.\n"); } obj2 = obj_list; i = 1; do if (obj2->next_all == ob) { (void)snprintf(tdb, sizeof(tdb), "Previous object in object list: OBJ(%s)\n", obj2->name); (void)strcat(db_buff, tdb); (void)sprintf(tdb, "position in object list:%d\n",i); (void)strcat(db_buff, tdb); } while (obj_list != (obj2 = obj2->next_all)); } else if (argv[0].u.number == 1) { if (argv[1].type != T_OBJECT) break; ob = argv[1].u.ob; (void)sprintf(db_buff,"program ref's %d\n", ob->prog->ref); (void)snprintf(tdb, sizeof(tdb), "Name %s\n", ob->prog->name); (void)strcat(db_buff, tdb); (void)sprintf(tdb,"program size %d\n", ob->prog->program_size); (void)strcat(db_buff, tdb); (void)sprintf(tdb, "num func's %u (%u) \n", ob->prog->num_functions ,ob->prog->num_functions * (unsigned) sizeof(struct function)); (void)strcat(db_buff, tdb); (void)sprintf(tdb,"sizeof rodata %d\n", ob->prog->rodata_size); (void)strcat(db_buff, tdb); (void)sprintf(tdb,"num vars %u (%u)\n", ob->prog->num_variables ,ob->prog->num_variables * (unsigned) sizeof(struct variable)); (void)strcat(db_buff, tdb); (void)sprintf(tdb,"num inherits %u (%u)\n", ob->prog->num_inherited ,ob->prog->num_inherited * (unsigned) sizeof(struct inherit)); (void)strcat(db_buff, tdb); (void)sprintf(tdb,"total size %d\n", ob->prog->total_size); (void)strcat(db_buff, tdb); } else { (void)sprintf(db_buff, "Bad number argument to object_info: %lld\n", argv[0].u.number); } retval.type = T_STRING; retval.string_type = STRING_MSTRING; retval.u.string = make_mstring(db_buff); return &retval; } case 19: /* opcdump, 19 */ { #ifdef OPCPROF opcdump(); retval = const1; return &retval; #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with OPCPROF flag.\n"; return &retval; #endif } case 20: /* send_udp, 20 host, port, msg */ { #ifdef CATCH_UDP_PORT extern udpsvc_t *udpsvc; #endif if (argc < 3 || argv[0].type != T_STRING || argv[1].type != T_NUMBER || argv[2].type != T_STRING) break; #ifdef CATCH_UDP_PORT tmp = udpsvc_send(udpsvc, argv[0].u.string, argv[1].u.number, argv[2].u.string); if (tmp) retval = const1; else #endif retval = const0; return &retval; } case 21: /* mud_port, 21 */ { extern int port_number; retval.type = T_NUMBER; retval.u.number = port_number; return &retval; } case 22: /* udp_port, 22 */ { #ifdef CATCH_UDP_PORT extern int udp_port; retval.u.number = udp_port; #else retval.u.number = -1; #endif retval.type = T_NUMBER; return &retval; } case 23: /* set_wizard, object */ if (argc && (argv[0].type == T_OBJECT)) { retval = const1; return &retval; } else { retval = const0; return &retval; } case 24: /* ob_flags, 24 ob */ { if (argc && (argv[0].type == T_OBJECT)) { retval.type = T_NUMBER; retval.u.number = argv[0].u.ob->flags; return &retval; } retval = const0; return &retval; } case 25: /* get_variables, 25 object NULL/string */ { struct svalue get_variables(struct object *); struct svalue get_variable(struct object *, char *); switch (argc) { case 1: if ( argv[0].type != T_OBJECT) { retval = const0; return &retval; } retval = get_variables(argv[0].u.ob); return &retval; case 2: if ( argv[0].type != T_OBJECT || argv[1].type != T_STRING) { retval = const0; return &retval; } retval = get_variable(argv[0].u.ob, argv[1].u.string); return &retval; case 3: if ( argv[0].type == T_OBJECT && argv[1].type == T_STRING) { retval = get_variable(argv[0].u.ob, argv[1].u.string); return &retval; } if ( argv[0].type == T_OBJECT) { retval = get_variables(argv[0].u.ob); return &retval; } retval = const0; return &retval; default: retval = const0; return &retval; } } case 26: /* get_eval_cost, 26 */ { extern int eval_cost; retval.type = T_NUMBER; retval.u.number = eval_cost; return &retval; } case 27: /* debug malloc, 27 */ { retval = const1; return &retval; } case 28: /* getprofile, 28 object */ { int format = 0; #ifndef PROFILE_LPC retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with PROFILE_LPC flag.\n"; return &retval; #else if (argc < 1 || argv[0].type != T_OBJECT) break; if (argc >= 2 && argv[1].type == T_NUMBER) format = argv[1].u.number; if (format == 0) { retval.type = T_POINTER; retval.u.vec = allocate_array(argv[0].u.ob->prog->num_functions); for (il = 0; il < (int)argv[0].u.ob->prog->num_functions; il++) { (void)snprintf(buff, sizeof(buff), "%016lld:%020lld: %s", (long long)argv[0].u.ob->prog->functions[il].num_calls, (long long)(argv[0].u.ob->prog->functions[il].time_spent * 1e6), argv[0].u.ob->prog->functions[il].name); retval.u.vec->item[il].type = T_STRING; retval.u.vec->item[il].string_type = STRING_MSTRING; retval.u.vec->item[il].u.string = make_mstring(buff); } } else if (format == 1) { retval.type = T_POINTER; retval.u.vec = allocate_array(argv[0].u.ob->prog->num_functions); double now = current_cpu(); struct program *prog = argv[0].u.ob->prog; for (il = 0; il < (int)prog->num_functions; il++) { struct function *func = prog->functions + il; struct vector *res = allocate_array(7); update_func_profile(func, now, 0.0, 0.0, 0); res->item[0].type = T_STRING; res->item[0].string_type = STRING_MSTRING; res->item[0].u.string = make_mstring(func->name); res->item[1].type = T_FLOAT; res->item[1].u.real = func->time_spent * 1e6; res->item[2].type = T_FLOAT; res->item[2].u.real = func->tot_time_spent * 1e6; res->item[3].type = T_FLOAT; res->item[3].u.real = func->num_calls; res->item[4].type = T_FLOAT; res->item[4].u.real = func->avg_time * 1e6; res->item[5].type = T_FLOAT; res->item[5].u.real = func->avg_tot_time * 1e6; res->item[6].type = T_FLOAT; res->item[6].u.real = func->avg_calls; retval.u.vec->item[il].type = T_POINTER; retval.u.vec->item[il].u.vec = res; } } else { retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Unknown format.\n"; } return &retval; #endif } case 29: /* get_avg_response, 29 */ { extern int get_msecs_response(int); extern int msr_point; int sum, num, tmp; if (msr_point >=0) { sum = 0; num = 0; for (il = 0; il < 100; il++) { if ((tmp = get_msecs_response(il)) >=0) { sum += tmp; num++; } } retval.type = T_NUMBER; retval.u.number = (num > 0) ? sum / num : 0; return &retval; } break; } case 30: /* destruct, 30 */ case 31: /* destroy, 31 */ { extern void destruct_object(struct object *); if (argc && argv[0].type == T_OBJECT && !(argv[0].u.ob->flags & O_DESTRUCTED)) destruct_object(argv[0].u.ob); break; } case 32: /* update snoops, 31 */ #ifdef SUPER_SNOOP update_snoop_file(); #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with SUPER_SNOOP flag.\n"; #endif break; case 33: /* call_warnings, int 0 = off, 1 = on */ if (argc && (argv[0].type == T_STRING)) { if (strcmp(argv[0].u.string, "on") == 0) call_warnings++; else call_warnings = call_warnings > 0 ? call_warnings - 1 : 0; retval.type = T_NUMBER; retval.u.number = call_warnings; return &retval; } else { retval.type = T_NUMBER; retval.u.number = -1; return &retval; } case 34: /* dump objects */ { FILE *ufile; struct object *ob; if ((ufile = fopen(OBJECT_DUMP_FILE, "w")) == NULL) { retval.type = T_NUMBER; retval.u.number = -1; return &retval; } fputs("Array (size), Mapping (size), String (size), Objs, Ints, Floats, Inventory, Callouts, Environment, Name\n", ufile); ob = obj_list; do { mem_variables(ufile, ob); } while (obj_list != (ob = ob->next_all)); (void)fclose(ufile); break; } case 35: /* query_debug_ob */ if (!argc || argv[0].type != T_OBJECT) break; retval.type = T_NUMBER; retval.u.number = argv[0].u.ob->debug_flags; return &retval; case 36: /* set_debug_ob */ if (!argc || argv[0].type != T_OBJECT || argv[1].type != T_NUMBER) break; retval.type = T_NUMBER; retval.u.number = argv[0].u.ob->debug_flags; argv[0].u.ob->debug_flags = argv[1].u.number; return &retval; case 37: /* set_swap */ retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Obsolete function.\n"; return &retval; case 38: /* query_swap */ retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Obsolete function.\n"; return &retval; case 39: /* query_debug_prog */ if (!argc || argv[0].type != T_OBJECT) break; retval.type = T_NUMBER; retval.u.number = argv[0].u.ob->prog->debug_flags; return &retval; case 40: /* set_debug_prog */ if (argc < 2 || argv[0].type != T_OBJECT || argv[1].type != T_NUMBER) break; retval.type = T_NUMBER; retval.u.number = argv[0].u.ob->prog->debug_flags; argv[0].u.ob->prog->debug_flags = argv[1].u.number; return &retval; #ifdef FUNCDEBUG case 41: dumpfuncs(); retval = const0; return &retval; #endif case 42: /* inhibitcallouts */ if (argc && (argv[0].type == T_STRING)) { extern int inhibitcallouts; int old; old = inhibitcallouts; if (strcmp(argv[0].u.string, "on") == 0) inhibitcallouts = 1; else inhibitcallouts = 0; retval.type = T_NUMBER; retval.u.number = old; return &retval; } else { retval.type = T_NUMBER; retval.u.number = -1; return &retval; } case 43: /* inhibitcallouts */ if (argc && (argv[0].type == T_STRING)) { extern int warnobsoleteflag; int old; old = warnobsoleteflag; if (strcmp(argv[0].u.string, "on") == 0) warnobsoleteflag = 1; else warnobsoleteflag = 0; retval.type = T_NUMBER; retval.u.number = old; return &retval; } else { retval.type = T_NUMBER; retval.u.number = -1; return &retval; } case 44: /* shared_strings */ #ifdef DEBUG dump_sstrings(); retval = const0; #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with DEBUG flag.\n"; #endif return &retval; case 45: /* dump_alarms */ { int c; FILE *ufile; if ((ufile = fopen(ALARM_DUMP_FILE, "w")) == NULL) { retval.type = T_NUMBER; retval.u.number = -1; return &retval; } c = dump_callouts(ufile); fclose(ufile); retval.type = T_NUMBER; retval.u.number = c; return &retval; } #ifdef PROFILE_LPC case 46: /* top_ten_cpu */ { #define NUMBER_OF_TOP_TEN 100 struct program *p[NUMBER_OF_TOP_TEN]; struct program *prog; struct vector *v; int i, j; double now = current_cpu(); for(i = 0; i < NUMBER_OF_TOP_TEN; i++) p[i] = (struct program *)0L; prog = prog_list; do { update_prog_profile(prog, now, 0.0, 0.0); for(i = NUMBER_OF_TOP_TEN-1; i >= 0; i--) { if ( p[i] && (prog->cpu_avg <= p[i]->cpu_avg)) break; } if (i < (NUMBER_OF_TOP_TEN - 1)) for (j = 0; j <= i; j++) if (strcmp(p[j]->name,prog->name) == 0) { i = NUMBER_OF_TOP_TEN-1; break; } if (i < (NUMBER_OF_TOP_TEN - 1)) { j = NUMBER_OF_TOP_TEN - 2; while(j > i) { p[j + 1] = p[j]; j--; } p[i + 1] = prog; } } while (prog_list != (prog = prog->next_all)); v = make_cpu_array2(NUMBER_OF_TOP_TEN, p); if (v) { retval.type = T_POINTER; retval.u.vec = v; return &retval; } break; #undef NUMBER_OF_TOP_TEN } #else case 46: retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with PROFILE_LPC flag.\n"; return &retval; #endif case 47: /* object_cpu_avg object */ { #if defined(PROFILE_LPC) if (argc < 1 || (argv[0].type != T_OBJECT)) break; update_prog_profile(argv[0].u.ob->prog, current_cpu(), 0.0, 0.0); retval.type = T_FLOAT; retval.u.number =argv[0].u.ob->prog->cpu_avg * 1e6; return &retval; #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with PROFILE_LPC flag.\n"; return &retval; #endif } case 48: /* getprofile_avg, 28 object */ { #if defined(PROFILE_LPC) if (argc < 1 || argv[0].type != T_OBJECT) break; retval.type = T_POINTER; retval.u.vec = allocate_array(argv[0].u.ob->prog->num_functions); double now = current_cpu(); struct program *prog = argv[0].u.ob->prog; for (il = 0; il < (int)prog->num_functions; il++) { struct function *func = prog->functions + il; struct vector *res = allocate_array(3); update_func_profile(func, now, 0.0, 0.0, 0); res->item[0].type = T_STRING; res->item[0].string_type = STRING_MSTRING; res->item[0].u.string = make_mstring(func->name); res->item[1].type = T_FLOAT; res->item[1].u.real = func->avg_time * 1e6; res->item[2].type = T_FLOAT; res->item[2].u.real = func->avg_calls; retval.u.vec->item[il].type = T_POINTER; retval.u.vec->item[il].u.vec = res; } return &retval; #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with PROFILE_LPC flag.\n"; return &retval; #endif } case 49: /* profile_timebase */ { #if defined(PROFILE_LPC) if (argc < 1) { /* Return current value */ retval.type = T_FLOAT; retval.u.real = get_profile_timebase(); return &retval; } /* Update using old timebase */ double now = current_cpu(); struct program *prog = prog_list; do { update_prog_profile(prog, now, 0.0, 0.0); for (int i = 0; i < prog->num_functions; i++) { struct function *func = prog->functions + i; update_func_profile(func, now, 0.0, 0.0, 0); } } while (prog_list != (prog = prog->next_all)); /* Set the new value */ if (argv[0].type == T_NUMBER && argv[0].u.number > 0) set_profile_timebase(argv[0].u.number); else if (argv[0].type == T_FLOAT && argv[0].u.real > 1e-3) set_profile_timebase(argv[0].u.real); else break; retval = const1; return &retval; #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with PROFILE_LPC flag.\n"; return &retval; #endif } case 50: { #ifdef PROFILE_LPC extern int trace_calls; extern FILE *trace_calls_file; if (argc < 1 || argv[0].type != T_NUMBER) break; if (!trace_calls && argv[0].u.number) { if ((trace_calls_file = fopen(TRACE_CALLS_FILE, "w")) == 0) break; setvbuf(trace_calls_file, 0, _IOFBF, 1<<20); /* Set a 1MB buffer */ trace_calls = 1; } else if (trace_calls && !argv[0].u.number) { fclose(trace_calls_file); trace_calls_file = 0; trace_calls = 0; } retval = const1; return &retval; #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with PROFILE_LPC.\n"; return &retval; #endif } case 51: { #if defined(PROFILE_LPC) long long num_top, criteria, num_items = 0; double now = current_cpu(), crit_val; struct program *prog; struct { struct program *prog; double crit_val; unsigned short func_index; } *result; if (argc < 2 || argv[0].type != T_NUMBER || argv[1].type != T_NUMBER) break; num_top = argv[0].u.number; criteria = argv[1].u.number; if (num_top < 0 || num_top > 1000) { retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "The number of itmes must be >= 0 and <= 1000."; break; } if (criteria < 0 || criteria > 9) { retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "The criteria must be >= 0 and <= 9."; break; } if (num_top == 0) { retval.type = T_POINTER; retval.u.vec = allocate_array(0); return &retval; } result = xalloc(sizeof(*result) * (num_top + 1)); memset(result, 0, sizeof(*result) * (num_top + 1)); prog = prog_list; do { update_prog_profile(prog, now, 0.0, 0.0); for (int i = 0; i < prog->num_functions; i++) { struct function *func = prog->functions + i; update_func_profile(func, now, 0.0, 0.0, 0); crit_val = get_top_func_criteria(func, criteria); if (num_items == num_top && result[num_items - 1].crit_val >= crit_val) continue; if (num_items == 0 || (num_items < num_top && result[num_items - 1].crit_val >= crit_val)) { result[num_items].prog = prog; result[num_items].func_index = i; result[num_items].crit_val = crit_val; num_items++; } else { int insert = num_items; while (insert > 0 && result[insert - 1].crit_val < crit_val) insert--; memmove(&result[insert + 1], &result[insert], sizeof(*result) * (num_items - insert)); result[insert].prog = prog; result[insert].func_index = i; result[insert].crit_val = crit_val; if (num_items < num_top) num_items++; } } } while ((prog = prog->next_all) != prog_list); retval.type = T_POINTER; retval.u.vec = allocate_array(num_items); for (int i = 0; i < num_items; i++) { struct vector *val = allocate_array(9); prog = result[i].prog; struct function *func = &prog->functions[result[i].func_index]; crit_val = result[i].crit_val; val->item[0].type = T_STRING; val->item[0].string_type = STRING_MSTRING; val->item[0].u.string = make_mstring(prog->name); val->item[1].type = T_STRING; val->item[1].string_type = STRING_SSTRING; val->item[1].u.string = func->name; reference_sstring(func->name); val->item[2].type = T_FLOAT; val->item[2].u.real = crit_val; val->item[3].type = T_FLOAT; val->item[3].u.real = func->time_spent; val->item[4].type = T_FLOAT; val->item[4].u.real = func->avg_time; val->item[5].type = T_FLOAT; val->item[5].u.real = func->tot_time_spent; val->item[6].type = T_FLOAT; val->item[6].u.real = func->avg_tot_time; val->item[7].type = T_FLOAT; val->item[7].u.real = func->num_calls; val->item[8].type = T_FLOAT; val->item[8].u.real = func->avg_calls; retval.u.vec->item[i].type = T_POINTER; retval.u.vec->item[i].u.vec = val; } free(result); return &retval; #else retval.type = T_STRING; retval.string_type = STRING_CSTRING; retval.u.string = "Only valid if GD compiled with PROFILE_LPC.\n"; return &retval; #endif } } retval = const0; return &retval; }
int StateConstraints::fireVectorSize(const PetriNet& net, const MarkVal* m0, const VarVal*) const{ assert(nPlaces == net.numberOfPlaces()); assert(nVars == net.numberOfVariables()); // Create linary problem lprec* lp; lp = make_lp(0, net.numberOfTransitions()); // One variable for each entry in the firing vector assert(lp); if(!lp) return false; // Set verbosity set_verbose(lp, IMPORTANT); // Set transition names (not strictly needed) for(size_t i = 0; i < net.numberOfTransitions(); i++) set_col_name(lp, i+1, const_cast<char*>(net.transitionNames()[i].c_str())); // Start adding rows set_add_rowmode(lp, TRUE); REAL row[net.numberOfTransitions() + 1]; for(size_t p = 0; p < nPlaces; p++){ // Set row zero memset(row, 0, sizeof(REAL) * net.numberOfTransitions() + 1); for(size_t t = 0; t < net.numberOfTransitions(); t++){ int d = net.outArc(t, p) - net.inArc(p, t); row[1+t] = d; } if(pcs[p].min == pcs[p].max && pcs[p].max != CONSTRAINT_INFTY){ double target = pcs[p].min - m0[p]; add_constraint(lp, row, EQ, target); }else{ // There's always a min, even zero is interesting double target = pcs[p].min - m0[p]; add_constraint(lp, row, GE, target); if(pcs[p].max != CONSTRAINT_INFTY){ double target = pcs[p].max - m0[p]; add_constraint(lp, row, LE, target); } } } // Finished adding rows set_add_rowmode(lp, FALSE); // Create objective memset(row, 0, sizeof(REAL) * net.numberOfTransitions() + 1); for(size_t t = 0; t < net.numberOfTransitions(); t++) row[1+t] = 1; // The sum the components in the firing vector // Set objective set_obj_fn(lp, row); // Minimize the objective set_minim(lp); // Set variables as integer variables for(size_t i = 0; i < net.numberOfTransitions(); i++) set_int(lp, 1+i, TRUE); // Attempt to solve the problem int result = solve(lp); // Limit on traps to test size_t traplimit = nPlaces * OVER_APPROX_TRAP_FACTOR; // Try to add a minimal trap constraint while((result == OPTIMAL) && traplimit-- < 0){ memset(row, 0, sizeof(REAL) * net.numberOfTransitions() + 1); // Get the firing vector get_variables(lp, row); // Compute the resulting marking MarkVal rMark[net.numberOfPlaces()]; for(size_t p = 0; p < nPlaces; p++){ rMark[p] = m0[p]; for(size_t t = 0; t < net.numberOfTransitions(); t++) rMark[p] += (net.outArc(t, p) - net.inArc(p, t)) * (int)row[t]; } // Find an M-trap BitField trap(minimalTrap(net, m0, rMark)); //Break if there's no trap if(trap.none()) break; // Compute the new equation for(size_t t = 0; t < net.numberOfTransitions(); t++){ row[1+t] = 0; for(size_t p = 0; p < nPlaces; p++) if(trap.test(p)) row[1+t] += net.outArc(t, p) - net.inArc(p, t); } // Add a new row with target as greater than equal to 1 set_add_rowmode(lp, TRUE); add_constraint(lp, row, GE, 1); set_add_rowmode(lp, FALSE); // Attempt to solve the again result = solve(lp); } int retval = 0; if(result != INFEASIBLE){ get_variables(lp, row); for(size_t t = 0; t < net.numberOfTransitions(); t++) retval += (int)row[t]; } // Delete the linear problem delete_lp(lp); lp = NULL; // Return true, if it was infeasible return retval; }
/** \brief Compute search direction using cholesky method (m > n). * */ void compute_searchdir_chol_thin(problem_data_t *pdat, variables_t *vars, double t, dmatrix *B, dmatrix *BB, double *tm1, double *bDA, double *d3) { int i, m, n; double bDb, bDbinv; dmatrix *matX1, *matX2; double lambda, tinv; double *g, *h, *z, *expz, *expmz, *ac, *ar, *b, *d1, *d2, *Aw; double *x, *v, *w, *u, *dx, *dv, *dw, *du, *gv, *gw, *gu, *gx; get_problem_data(pdat, &matX1, &matX2, &ac, &ar, &b, &lambda); get_variables(vars, &x, &v, &w, &u, &dx, &dv, &dw, &du, &gx, &gv, &gw, &gu, &g, &h, &z, &expz, &expmz, &d1, &d2, &Aw); m = matX1->m; n = matX1->n; tinv = 1.0 / t; /* bDb, Db */ bDb = 0.0; for (i = 0; i < m; i++) { tm1[i] = h[i] * b[i]; /* tm1 = Db */ bDb += b[i] * tm1[i]; } bDbinv = 1.0 / bDb; /* bDA */ dmat_yATx(matX1, tm1, bDA); dmat_copy(matX1, B); /* B = A */ dmat_ysqrtx(m, h, tm1); /* tm1 = D^{1/2} */ /* B = D^{1/2}*B */ dmat_diagscale(B, tm1, FALSE, NULL, FALSE); /* BB = A^T*D*A */ dmat_B_ATA(B, BB); /* BB = B^T*B */ for (i = 0; i < n; i++) { double q1, q2, q3, ui, wi, gr2; ui = u[i]; wi = w[i]; q1 = 1.0 / (ui + wi); q2 = 1.0 / (ui - wi); q3 = ui * ui + wi * wi; gw[i] -= (q1 - q2) * tinv; /* A'*g - (q1-q2) */ gu[i] = lambda - (q1 + q2) * tinv; /* lambda - (q1+q2) */ d1[i] = (q1 * q1 + q2 * q2) * tinv; d2[i] = (q1 * q1 - q2 * q2) * tinv; d3[i] = 2 / q3 * tinv; /* dw = (bDA'*gv-bDb*gr2); */ gr2 = gw[i] + 2 * gu[i] * ui * wi / q3; dw[i] = bDA[i] * gv[0] * bDbinv - gr2; } /* dw = (bDb*S-bDA'*bDA)\(bDA'*gv-bDb*gr2); = (S-1/bDb)*bDA'*bDA)\(bDA'*(gv/bDb)-gr2); */ dmat_diagadd(BB, d3); dmat_A_axxTpA(-bDbinv, bDA, BB); dmat_posv(BB, dw); /* dv = (-bDA*dw-gv)/bDb; */ dv[0] = -(dmat_dot(n, bDA, dw) + gv[0]) / bDb; /* du = -(gu+d2.*dw)./d1; */ for (i = 0; i < n; i++) du[i] = -(gu[i] + d2[i] * dw[i]) / d1[i]; }
//Execute function int LPSolveClass::Execute() { /* std::cout << "---------------------------------\n"; std::cout << "objective function\n"; for (unsigned int i = 0; i < coefficients.size(); i++) std::cout << coefficients[i] << "\t"; std::cout << "\nConstant Value = " << obj_const << std::endl; std::cout << "---------------------------------\n"; std::cout << "Equality Constraints\n"; for (unsigned int i = 0; i < A_equ.size(); i++){ //std::cout << "Row index = " << i << "\t\t"; for (unsigned int j = 0; j < A_equ[i].size(); j++) std::cout << A_equ[i][j] << "\t"; std::cout << "\n"; } std::cout << "b\n"; for (unsigned int i = 0; i < b_equ.size(); i++) std::cout << b_equ[i] << "\t"; std::cout << "\n"; std::cout << "---------------------------------\n"; std::cout << "InEquality Constraints\n"; for (unsigned int i = 0; i < A_inequ.size(); i++){ //std::cout << "Row index = " << i << "\t\t"; for (unsigned int j = 0; j < A_inequ[i].size(); j++) std::cout << A_inequ[i][j] << "\t"; std::cout << "\n"; } std::cout << "b\n"; for (unsigned int i = 0; i < b_inequ.size(); i++) std::cout << b_inequ[i] << "\t"; std::cout << "\n"; */ lprec *lp; int Ncol = coefficients.size(), *colno = NULL, j, ret = 0; REAL *row = NULL; /* We will build the model row by row So we start with creating a model with 0 rows and n columns */ lp = make_lp(0, Ncol); if (lp == NULL) ret = 1;/* couldn't construct a new model... */ if (ret == 0){ //let us name our variables std::string s = "x"; for (int i = 0; i < Ncol; i++){ std::stringstream out; out << i; s = s + out.str(); char *cpy = new char[s.size()+1] ; strcpy(cpy, s.c_str()); set_col_name(lp, i+1, cpy); } /* create space large enough for one row */ colno = (int *) malloc(Ncol * sizeof(*colno)); row = (REAL *) malloc(Ncol * sizeof(*row)); if ((colno == NULL) || (row == NULL)) ret = 2; } set_add_rowmode(lp, TRUE); //add the equation constraints if (ret == 0){ /* makes building the model faster if it is done rows by row */ if (A_equ.size() > 0){ for (unsigned int i = 0; i < A_equ.size(); i++){//loop over the rows of equality constraints for (unsigned int j = 0; j < A_equ[i].size(); j++){//loop over the columns of equality constraints colno[j] = j+1;//add the j-th column to lpsolve row[j] = A_equ[i][j]; } /* add the row to lpsolve */ if(!add_constraintex(lp, A_equ[i].size(), row, colno, EQ, b_equ[i])) ret = 2; } } } //add the inequality constraints if (ret == 0){ /* makes building the model faster if it is done rows by row */ if (A_inequ.size() > 0){ for (unsigned int i = 0; i < A_inequ.size(); i++){//loop over the rows of inequality constraints for (unsigned int j = 0; j < A_inequ[i].size(); j++){//loop over the columns of inequality constraints colno[j] = j+1;//add the j-th column to lpsolve row[j] = A_inequ[i][j]; } /* add the row to lpsolve */ if(!add_constraintex(lp, A_inequ[i].size(), row, colno, LE, b_inequ[i])) ret = 3; } } } //add the const constraint if (ret == 0){ if (b_const.size()>0){ for (unsigned int i = 0; i < b_const.size(); i++){ if (b_const[i] > 0){ for (unsigned int j = 0; j < b_const.size(); j++){ if (i == j){ colno[j] = j+1;//add the j-th column to lpsolve row[j] = 1.0; } else{ colno[j] = j+1;//add the j-th column to lpsolve row[j] = 0.0; } } if(!add_constraintex(lp, b_const.size(), row, colno, EQ, b_const[i])) ret = 4; } } } } //set the variables to be integer if (ret == 0){ for (int i = 0; i < Ncol; i++) set_int(lp, i+1, TRUE); } /* rowmode should be turned off again when done building the model */ set_add_rowmode(lp, FALSE); //add the objective function if (ret == 0){ //set the objective function for (unsigned int i = 0; i < coefficients.size(); i++){ colno[i] = i+1; row[i] = coefficients[i]; } //set the objective in lpsolve if(!set_obj_fnex(lp, coefficients.size(), row, colno)) ret = 4; } //set the objective to minimize if (ret == 0){ set_minim(lp); /* just out of curioucity, now show the model in lp format on screen */ /* this only works if this is a console application. If not, use write_lp and a filename */ write_LP(lp, stdout); /* I only want to see important messages on screen while solving */ set_verbose(lp, IMPORTANT); /* Now let lpsolve calculate a solution */ ret = solve(lp); if(ret == OPTIMAL) ret = 0; else ret = 5; } //get some results if (ret == 0){ /* a solution is calculated, now lets get some results */ /* objective value */ std::cout << "Objective value: " << get_objective(lp) << std::endl; /* variable values */ get_variables(lp, row); /* variable values */ variables.resize(Ncol); for(j = 0; j < Ncol; j++) variables[j] = row[j]; /* we are done now */ } else{ std::cout << "The optimal value can't be solved for linear programming, please check the constraints!!\n"; exit(1); } std::cout << "print the result\t # of line segments is \n"; for (int i = 0; i < Ncol; i++) std::cout << "index = " << i << "\t# = " << variables[i] << std::endl; /* free allocated memory */ if(row != NULL) free(row); if(colno != NULL) free(colno); /* clean up such that all used memory by lpsolve is freed */ if (lp != NULL) delete_lp(lp); return ret; }
/* * updates autos list */ void update_autos() { gchar command[1000]; /* remove all previous GDB variables for autos */ GList *iter = autos; while (iter) { variable *var = (variable*)iter->data; sprintf(command, "-var-delete %s", var->internal->str); exec_sync_command(command, TRUE, NULL); iter = iter->next; } g_list_foreach(autos, (GFunc)variable_free, NULL); g_list_free(autos); autos = NULL; /* add current autos to the list */ GList *unevaluated = NULL; const char *gdb_commands[] = { "-stack-list-arguments 0 0 0", "-stack-list-locals 0" }; int i, size = sizeof (gdb_commands) / sizeof(char*); for (i = 0; i < size; i++) { gchar *record = NULL; result_class rc = exec_sync_command(gdb_commands[i], TRUE, &record); if (RC_DONE != rc) break; gchar *pos = record; while ((pos = strstr(pos, "name=\""))) { pos += strlen("name=\""); *(strchr(pos, '\"')) = '\0'; variable *var = variable_new(pos, i ? VT_LOCAL : VT_ARGUMENT); /* create new gdb variable */ gchar *create_record = NULL; gchar *escaped = g_strescape(pos, NULL); sprintf(command, "-var-create - * \"%s\"", escaped); g_free(escaped); /* form new variable */ if (RC_DONE == exec_sync_command(command, TRUE, &create_record)) { gchar *intname = strstr(create_record, "name=\"") + strlen ("name=\""); *strchr(intname, '\"') = '\0'; var->evaluated = TRUE; g_string_assign(var->internal, intname); autos = g_list_append(autos, var); g_free(create_record); } else { var->evaluated = FALSE; g_string_assign(var->internal, ""); unevaluated = g_list_append(unevaluated, var); } pos += strlen(pos) + 1; } g_free(record); } /* get values for the autos (without incorrect variables) */ get_variables(autos); /* add incorrect variables */ autos = g_list_concat(autos, unevaluated); }
int demo() { lprec *lp; int Ncol, *colno = NULL, j, ret = 0; REAL *row = NULL; /* We will build the model row by row So we start with creating a model with 0 rows and 2 columns */ Ncol = 2; /* there are two variables in the model */ lp = make_lp(0, Ncol); if(lp == NULL) ret = 1; /* couldn't construct a new model... */ if(ret == 0) { /* let us name our variables. Not required, but can be useful for debugging */ set_col_name(lp, 1, "x"); set_col_name(lp, 2, "y"); /* create space large enough for one row */ colno = (int *) malloc(Ncol * sizeof(*colno)); row = (REAL *) malloc(Ncol * sizeof(*row)); if((colno == NULL) || (row == NULL)) ret = 2; } if(ret == 0) { set_add_rowmode(lp, TRUE); /* makes building the model faster if it is done rows by row */ /* construct first row (120 x + 210 y <= 15000) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 120; colno[j] = 2; /* second column */ row[j++] = 210; /* add the row to lpsolve */ if(!add_constraintex(lp, j, row, colno, LE, 15000)) ret = 3; } if(ret == 0) { /* construct second row (110 x + 30 y <= 4000) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 110; colno[j] = 2; /* second column */ row[j++] = 30; /* add the row to lpsolve */ if(!add_constraintex(lp, j, row, colno, LE, 4000)) ret = 3; } if(ret == 0) { /* construct third row (x + y <= 75) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 1; colno[j] = 2; /* second column */ row[j++] = 1; /* add the row to lpsolve */ if(!add_constraintex(lp, j, row, colno, LE, 75)) ret = 3; } if(ret == 0) { set_add_rowmode(lp, FALSE); /* rowmode should be turned off again when done building the model */ /* set the objective function (143 x + 60 y) */ j = 0; colno[j] = 1; /* first column */ row[j++] = 143; colno[j] = 2; /* second column */ row[j++] = 60; /* set the objective in lpsolve */ if(!set_obj_fnex(lp, j, row, colno)) ret = 4; } if(ret == 0) { /* set the object direction to maximize */ set_maxim(lp); /* just out of curioucity, now show the model in lp format on screen */ /* this only works if this is a console application. If not, use write_lp and a filename */ write_LP(lp, stdout); /* write_lp(lp, "model.lp"); */ /* I only want to see important messages on screen while solving */ set_verbose(lp, IMPORTANT); /* Now let lpsolve calculate a solution */ ret = solve(lp); if(ret == OPTIMAL) ret = 0; else ret = 5; } if(ret == 0) { /* a solution is calculated, now lets get some results */ /* objective value */ printf("Objective value: %f\n", get_objective(lp)); /* variable values */ get_variables(lp, row); for(j = 0; j < Ncol; j++) printf("%s: %f\n", get_col_name(lp, j + 1), row[j]); /* we are done now */ } /* free allocated memory */ if(row != NULL) free(row); if(colno != NULL) free(colno); if(lp != NULL) { /* clean up such that all used memory by lpsolve is freed */ delete_lp(lp); } return(ret); }
int calculate (IN int nCols /* variables in the model */, IN int nRows, IN double** rows, IN double* rights, IN double* objectives, OUT int* answer, IN int verbose) { lprec *lp; int result = 0; char *str = NULL; int *colno = NULL; double *row = NULL; /* We will build the model row by row * So we start with creating a model * with 0 rows and 2 columns */ if ( !(lp = make_lp (0, nCols)) ) { /* couldn't construct a new model... */ result = 1; goto RESULT; } if ( !(str = (char*) malloc ((log10 (nCols) + 10) * sizeof (*str))) ) { result = 2; goto RESULT; } /* let us name our variables. Not required, * but can be useful for debugging */ for ( int i = 1; i <= nCols; ++i ) { str[0] = 't'; _itoa (i, str + 1, 10); set_col_name (lp, i, str); // set_int (lp, i, TRUE); } /* create space large enough for one row */ colno = (int *) malloc (nCols * sizeof (*colno)); row = (double*) malloc (nCols * sizeof (*row)); if ( (colno == NULL) || (row == NULL) ) { result = 2; goto RESULT; } for ( int j = 0; j < nCols; ++j ) { colno[j] = j + 1; /* (j + 1) column */ } /* makes building the model faster if it is done rows by row */ set_add_rowmode (lp, TRUE); for ( int i = 0; i < nRows; ++i ) { // /* construct j row */ // for ( int j = 0; j < nCols; ++j ) // { row[j] = ??? ; } /* (210 * t2 + 156 * t3 == 0.0178) */ /* (230 * t2 + 160 * t3 == 0.0176) */ /* add the row to lp_solve */ if ( !add_constraintex (lp, nCols, rows[i], colno, EQ, rights[i]) ) { result = 3; goto RESULT; } } /* rowmode should be turned off again when done building the model */ set_add_rowmode (lp, FALSE); // /* set the objective function */ // for ( int j = 0; j < nCols; ++j ) // { row[j] = objectives[j]; } /* (t1 + t2 + t3 + t4) */ /* set the objective in lp_solve */ if ( !set_obj_fnex (lp, nCols, objectives, colno) ) { result = 4; goto RESULT; } /* set the object direction to maximize */ set_minim (lp); if ( verbose ) { /* just out of curioucity, now show the model in lp format on screen */ /* this only works if this is a console application. If not, use write_lp and a filename */ write_LP (lp, stdout); /* write_lp(lp, "model.lp"); */ } /* I only want to see important messages on screen while solving */ set_verbose (lp, IMPORTANT); /* Now let lpsolve calculate a solution */ result = solve (lp); if ( result == OPTIMAL ) { result = 0; } else { result = 5; goto RESULT; } /* a solution is calculated, * now lets get some results */ if ( verbose ) { /* objective value */ printf ("Objective value: %f\n", get_objective (lp)); } /* variable values */ get_variables (lp, row); for ( int j = 0; j < nCols; j++ ) { if ( verbose ) printf ("%s: %f\n", get_col_name (lp, j + 1), row[j]); answer[j] = row[j]; } /* we are done now */ RESULT:; /* free allocated memory */ if ( str != NULL )free (str); if ( row != NULL ) free (row); if ( colno != NULL ) free (colno); if ( lp != NULL ) { /* clean up such that all used memory by lpsolve is freed */ delete_lp (lp); } return result; }
double solve_constraints(int this_task) { lprec *lp; int numVar = 0, *var = NULL, ret = 0, i, j, k, var_count; double *coeff = NULL, lhs,rhs, obj; char col_name[10]; /* Creating a model */ for(i = 1;i < this_task; i++) numVar+=i; lp = make_lp(0, numVar); if(lp == NULL) ret = 1; /* Couldn't construct a new model */ if(ret == 0) { var_count = 1; for(i = 1 ; i < this_task; i++){ for(j = i+1 ; j <= this_task; j++) { sprintf(col_name, "%dNNP%d_%d", this_task, i, j); set_col_name(lp, var_count, col_name); var_count++; } } /* create space large enough for one row(i.e. equation) */ var = (int *) malloc(numVar * sizeof(*var)); coeff = (double *) malloc(numVar * sizeof(*coeff)); if((var == NULL) || (coeff == NULL)) ret = 2; } /* add the equations to lpsolve */ if(ret == 0) { set_add_rowmode(lp, TRUE); /* --------------------adding EQN-D-------------------- */ for(j = 2;j <= this_task;j++){ var_count = 0; for(i = 1; i < j; i++){ sprintf(col_name,"%dNNP%d_%d",this_task, i, j); var[var_count] = get_nameindex(lp, col_name, FALSE); coeff[var_count] = 1; var_count++; } lhs= 0; for(i = 1; i < j; i++) lhs+= nnp_min[i][j]; lhs*= floor(R[this_task]/task[j].p); rhs = 0; for(i = 1; i < j; i++) rhs += nnp_max[i][j]; rhs *= ceil(R[this_task]/task[j].p); if(!add_constraintex(lp, var_count, coeff, var, GE, lhs)) ret = 3; if(!add_constraintex(lp, var_count, coeff, var, LE, rhs)) ret = 3; } } if(ret == 0) { /* --------------------adding EQN-E-------------------- */ for(k = 2;k <= this_task;k++) { var_count = 0; for(j = 2; j <= k; j++){ for(i = 1; i < j; i++){ sprintf(col_name,"%dNNP%d_%d",this_task, i, j); var[var_count] = get_nameindex(lp, col_name, FALSE); coeff[var_count] = 1; var_count++; } } rhs = 0; for(i = 1; i < k; i++) rhs += ceil(R[this_task]/task[i].p); if(!add_constraintex(lp, var_count, coeff, var, LE,rhs)) ret = 3; } } if(ret == 0) { /* ------------------adding EQN-G & H------------------ */ for(j = 2; j <= this_task ; j++){ for(i = 1; i < j; i++){ lhs= floor(R[this_task]/task[j].p) * nnp_min[i][j]; sprintf(col_name,"%dNNP%d_%d",this_task, i, j); var[0] = get_nameindex(lp, col_name, FALSE); coeff[0] = 1; if(!add_constraintex(lp, 1, coeff, var, GE, lhs)) ret = 3; rhs = min(ceil(R[this_task]/task[i].p), ceil(R[this_task]/task[j].p) * ceil(R[j]/task[i].p), ceil(R[this_task]/task[j].p) * nnp_max[i][j]); if(!add_constraintex(lp, 1, coeff, var, LE,rhs)) ret = 3; } } } if(ret == 0) { /* --------------------adding EQN-I-------------------- */ for(i = 1; i < this_task; i++){ var_count = 0; for(j = i+1; j <= this_task; j++){ sprintf(col_name,"%dNNP%d_%d",this_task, i, j); var[var_count] = get_nameindex(lp, col_name, FALSE); coeff[var_count] = 1; var_count++; } rhs = ceil(R[this_task]/task[i].p); if(!add_constraintex(lp, var_count, coeff, var, LE,rhs)) ret = 3; } } set_add_rowmode(lp, FALSE); if(ret == 0) { /* -----------------set the objective----------------- */ var_count = 0; for(i = 1 ; i < this_task; i++){ for(j = i+1 ; j<= this_task; j++){ sprintf(col_name,"%dNNP%d_%d",this_task, i, j); var[var_count] = get_nameindex(lp, col_name, FALSE); coeff[var_count] = get_f(this_task, i, j); var_count++; } } if(!set_obj_fnex(lp, var_count, coeff, var)) ret = 4; set_maxim(lp); write_LP(lp, stdout); set_verbose(lp, IMPORTANT); ret = solve(lp); if(ret == OPTIMAL) ret = 0; else ret = 5; } if(ret == 0) { obj = get_objective(lp); /* Displaying calculated values */ /* variable values */ printf("\nVariable values:\n"); get_variables(lp, coeff); printf("\n"); for(j = 0; j < numVar; j++) printf("%s: %f\n", get_col_name(lp, j + 1), coeff[j]); /* objective value */ printf("\nObjective value: %f\n\n", obj); } printf("LP ERROR = %d\n\n", ret); /* free allocated memory */ if(coeff != NULL) free(coeff); if(var != NULL) free(var); if(lp != NULL) delete_lp(lp); return ret == 0 ? obj : 0; }
/* * updates watches list */ void update_watches() { gchar command[1000]; /* delete all GDB variables */ GList *iter = watches; while (iter) { variable *var = (variable*)iter->data; if (var->internal->len) { sprintf(command, "-var-delete %s", var->internal->str); exec_sync_command(command, TRUE, NULL); } /* reset all variables fields */ variable_reset(var); iter = iter->next; } /* create GDB variables, adding successfully created variables to the list then passed for updatind */ GList *updating = NULL; iter = watches; while (iter) { variable *var = (variable*)iter->data; /* try to create variable */ gchar *record = NULL; gchar *escaped = g_strescape(var->name->str, NULL); sprintf(command, "-var-create - * \"%s\"", escaped); g_free(escaped); if (RC_DONE != exec_sync_command(command, TRUE, &record)) { /* do not include to updating list, move to next watch */ var->evaluated = FALSE; g_string_assign(var->internal, ""); g_free(record); iter = iter->next; continue; } /* find and assign internal name */ gchar *pos = strstr(record, "name=\"") + strlen("name=\""); *strchr(pos, '\"') = '\0'; g_string_assign(var->internal, pos); g_free(record); var->evaluated = TRUE; /* add to updating list */ updating = g_list_append(updating, var); iter = iter->next; } /* update watches */ get_variables(updating); /* free updating list */ g_list_free(updating); }
/** \brief Compute search direction using pcg method. * */ void compute_searchdir_pcg(problem_data_t * pdat, variables_t * vars, double t, double s, double gap, pcg_status_t * pcgstat, adata_t * adata, mdata_t * mdata, double *precond, double *tmp_m1, double *A2h, double *tmp_x1) { int i, m, n, nz; double *p0, *p1, *p2, *p3; double normg, pcgtol, pcgmaxi, multfact; dmatrix *matX1, *matX2; double lambda, tinv; double *g, *h, *z, *expz, *expmz, *ac, *ar, *b, *d1, *d2, *Aw; double *x, *v, *w, *u, *dx, *dv, *dw, *du, *gv, *gw, *gu, *gx; static double pcgtol_factor = 1.0; get_problem_data(pdat, &matX1, &matX2, &ac, &ar, &b, &lambda); get_variables(vars, &x, &v, &w, &u, &dx, &dv, &dw, &du, &gx, &gv, &gw, &gu, &g, &h, &z, &expz, &expmz, &d1, &d2, &Aw); m = matX1->m; n = matX1->n; nz = matX1->nz; tinv = 1.0 / t; p0 = &precond[0]; p1 = &precond[1]; p2 = &precond[1+n]; p3 = &precond[1+n+n]; /* dmat_vset(n+n+1, 0, dx); */ dmat_yATx(matX2, h, A2h); /* A2h = A2'*h */ multfact = 0.0; if (ac != NULL) { /* h.*ac */ dmat_elemprod(m, h, ac, tmp_m1); dmat_vset(n, 0, tmp_x1); dmat_yAmpqTx(matX1, NULL, NULL, tmp_m1, tmp_x1); dmat_elemprod(n, ar, tmp_x1, tmp_x1); for (i = 0; i < m; i++) { multfact += h[i] * ac[i] * ac[i]; } } p0[0] = 0; for (i = 0; i < m; i++) { p0[0] += b[i] * b[i] * h[i]; } /* complete forming gradient and d1, d2, precond */ for (i = 0; i < n; i++) { double q1, q2, d3, div; q1 = 1.0 / (u[i] + w[i]); q2 = 1.0 / (u[i] - w[i]); gw[i] -= (q1 - q2) * tinv; /* A'*g - (q1-q2) */ gu[i] = lambda - (q1 + q2) * tinv; /* lambda - (q1+q2) */ d1[i] = (q1 * q1 + q2 * q2) * tinv; d2[i] = (q1 * q1 - q2 * q2) * tinv; if (ac != NULL) { d3 = A2h[i] + d1[i] + multfact*ar[i]*ar[i] - 2*tmp_x1[i]; } else { d3 = A2h[i] + d1[i]; } div = 1 / (d3 * d1[i] - d2[i] * d2[i]); p1[i] = d1[i] * div; p2[i] = d2[i] * div; p3[i] = d3 * div; } normg = dmat_norm2(n+n+1, gx); pcgtol = min(1e-1, 0.3*gap/min(1.0,normg)); /* pcgtol = min(1e-1, 0.3*gap/min(1.0,sqrt(normg))); */ pcgmaxi = MAX_PCG_ITER; if (s < 1e-5) { pcgtol_factor *= 0.5; } else { pcgtol_factor = 1.0; } pcgtol = pcgtol*pcgtol_factor; dmat_waxpby(n+n+1, -1, gx, 0, NULL, tmp_x1); pcg(dx, pcgstat, afun, adata, mfun, mdata, tmp_x1, pcgtol, pcgmaxi, n+n+1); }
/** \brief Compute search direction using cholesky method (m < n). * */ void compute_searchdir_chol_fat(problem_data_t *pdat, variables_t *vars, double t, dmatrix *B, dmatrix *BB, double *tm1, double *bDA, double *d3inv, double *tmp31, double *tmp32) { int i, m, n; double bDb; dmatrix *matX1, *matX2; double lambda, tinv; double *g, *h, *z, *expz, *expmz, *ac, *ar, *b, *d1, *d2, *Aw; double *x, *v, *w, *u, *dx, *dv, *dw, *du, *gv, *gw, *gu, *gx; get_problem_data(pdat, &matX1, &matX2, &ac, &ar, &b, &lambda); get_variables(vars, &x, &v, &w, &u, &dx, &dv, &dw, &du, &gx, &gv, &gw, &gu, &g, &h, &z, &expz, &expmz, &d1, &d2, &Aw); m = matX1->m; n = matX1->n; tinv = 1.0 / t; /* bDb, Db */ bDb = 0.0; for (i = 0; i < m; i++) { tm1[i] = h[i] * b[i]; /* tm1 = Db */ bDb += b[i] * tm1[i]; } /* bDA, D_inv */ dmat_yATx(matX1, tm1, bDA); dmat_copy(matX1, B); /* B = A */ dmat_yinvx(m, h, tm1); /* tm1 = D_inv */ for (i = 0; i < n; i++) { double ui, wi, q1, q2, q3, gr2; ui = u[i]; wi = w[i]; q1 = 1.0 / (ui + wi); q2 = 1.0 / (ui - wi); q3 = ui * ui + wi * wi; gw[i] -= (q1 - q2) * tinv; /* A'*g - (q1-q2) */ gu[i] = lambda - (q1 + q2)*tinv; /* lambda - (q1+q2) */ d1[i] = (q1 * q1 + q2 * q2) * tinv; d2[i] = (q1 * q1 - q2 * q2) * tinv; gr2 = gw[i] + 2 * gu[i] * ui * wi / q3; d3inv[i] = t * q3 / 2; /* en = d3^{-1} */ /* temporary use of tmp31 */ tmp31[i] = sqrt(d3inv[i]); /* store temporary values in dw, du */ dw[i] = d3inv[i] * bDA[i]; /* dw := d3inv.*bDA */ du[i] = d3inv[i] * gr2; /* du := d3inv.*gr2 */ } /* B = B*D3^{1/2} */ dmat_diagscale(B, NULL, FALSE, tmp31, FALSE); /* S = BB = ... */ /* BB = A*D3_inv*A^T */ dmat_B_AAT(B, BB); /* BB = B*B^T */ /* BB = D_inv + A*D3_inv*A^T */ dmat_diagadd(BB, tm1); /* SMW */ dmat_yAx(matX1, dw, tm1); dmat_posv(BB, tm1); dmat_yATx(matX1, tm1, tmp31); dmat_elemprod(n, d3inv, tmp31, tmp31); dmat_waxpby(n, -1, tmp31, 1, dw, tmp31); dmat_yAx(matX1, du, tm1); dmat_potrs(BB, tm1); dmat_yATx(matX1, tm1, tmp32); dmat_elemprod(n, d3inv, tmp32, tmp32); dmat_waxpby(n, -1, tmp32, 1, du, tmp32); dv[0] = (-gv[0] + dmat_dot(n,bDA,tmp32)) / (bDb - dmat_dot(n,bDA,tmp31)); /* dw = ... */ dmat_waxpby(n, -dv[0], tmp31, -1, tmp32, dw); /* du = -(gu+d2.*dw)./d1; */ for (i = 0; i < n; i++) du[i] = -(gu[i] + d2[i] * dw[i]) / d1[i]; }
vector<PathPoint *> LPPath :: findPath(vertex *curr) { lprec *lp; int numDropoff = 0; int numDropped = 0; int numPickup = 0; //find pairs for each dropoff point for(int i = 0; i < points.size(); i++) { if(points[i]->type == 1) { bool foundPair = false; for(int j = 0; j < points.size(); j++) { if(j != i && points[j]->pairIndex == points[i]->pairIndex) { pairIndex[i] = j; foundPair = true; break; } } //sometimes, there's an error and the pair cannot be found //in that case, print out some debugging information if(!foundPair) { cout << i << ":" << points[i]->pairIndex << " "; for(int j = 0; j < points.size(); j++) { cout << points[j]->type << ":" << points[j]->pairIndex << " "; } cout << endl; } } } //occasionally we encounter a model that takes hours or days to solve //we set a timeout on the solve function, and then advance to the next iteration //as the iteration increases, we introduce more randomness into the model // (this is done via the getNonZero function) for(int iteration = 0; ; iteration += 10) { //calculate cost matrix for(int i = 0; i < points.size(); i++) { PathPoint *ipoint = points[i]; if(ipoint->type == 0) numPickup++; else if(ipoint->type == 1) numDropoff++; else if(ipoint->type == 2) numDropped++; //from this point to itself costMatrix[i + 1][i] = getNonZero(0, iteration); //from this point to every other point for(int j = 0; j < points.size(); j++) { if(i != j) costMatrix[i + 1][j] = getNonZero(length(ipoint, points[j]), iteration); } //from the current location to this point costMatrix[0][i] = getNonZero(taxiPath->shortestPath(curr, ipoint->vert), iteration); } //calculate m matrix //first, we have to find earliest and latest //the current location must occur at time zero latest[0] = 0; for(int i = 0; i < points.size(); i++) { if(points[i]->type == 0 || points[i]->type == 2) { //this is a pickup or stand-alone dropoff point //the earliest time occurs when we go directly // from the current location to here //the latest time is set by the pickup constraint earliest[i] = costMatrix[0][i]; latest[i + 1] = points[i]->remaining; } else if(points[i]->type == 1) { //this is a dropoff point //the earliest time occurs when we go directly // to the pickup point, then here //the latest time occurs when we get to the pickup // point the latest, and then here the latest // (stretch both pickup and service constraints) earliest[i] = costMatrix[0][pairIndex[i]] + costMatrix[pairIndex[i] + 1][i]; latest[i + 1] = points[pairIndex[i]]->remaining + points[i]->remaining; } } //calculate m double test; for(int i = 0; i < points.size() + 1; i++) { for(int j = 0; j < points.size(); j++) { test = latest[i] + costMatrix[i][j] - earliest[j]; if(test > 0) m[i][j] = test; else m[i][j] = 0; } } //find the number of binary columns //each x_ij determines whether or not the taxi will move // from i to j //in the comments below these movements will be referred // to as route segments (_from_ i _to_ j) int ncol = (points.size() + 1) * points.size(); //find the total number of columns //besides the binary ones, there are ones for the time // at which the taxi will reach a point (B_i) int ncol_total = ncol + points.size() + 1; //create the lp instance lp = make_lp(0, ncol_total); //colno and row are used to define the constraints, and // later row will store the result from lpsolve //colno identifies the variable (column), and row identifies // the constants (multiplied by the variable); then, a // separate value determines the number of variables // that will be read (since we are using a sparse matrix - // otherwise we wouldn't need colno) //note**: column numbers are labeled starting from 1, not 0 int *colno = new int[ncol_total]; REAL *row = new REAL[ncol_total]; //since we're going to be adding constraints equation // by equation, we set add row mode to make it faster set_add_rowmode(lp, TRUE); //disable most output from lpsolve set_verbose(lp, CRITICAL); //set timeout of three seconds so we don't spend forever on this model set_timeout(lp, 3); //set up the binary constraints for(int i = 0; i < ncol; i++) { set_binary(lp, i + 1, TRUE); } //constraints 1 to 3 //these have one constraint per point for(int i = 0; i < points.size(); i++) { //1. the total number of route segments to here will // be equal to one for(int j = 0; j < points.size() + 1; j++) { colno[j] = j * points.size() + i + 1; row[j] = 1; } add_constraintex(lp, points.size() + 1, row, colno, EQ, 1); //2. there will be no route segment from here to itself colno[0] = (i + 1) * points.size() + i + 1; row[0] = 1; add_constraintex(lp, 1, row, colno, EQ, 0); //3. the total number of route segments from here will // be less than or equal to one (since the last point in // the route will be zero) for(int j = 0; j < points.size(); j++) { colno[j] = (i + 1) * points.size() + j + 1; row[j] = 1; } add_constraintex(lp, points.size(), row, colno, LE, 1); } //4. there will be exactly one route segment from the // current location for(int i = 0; i < points.size(); i++) { colno[i] = i + 1; row[i] = 1; } add_constraintex(lp, points.size(), row, colno, EQ, 1); //5. the relative time that the taxi reaches the current // location is zero colno[0] = ncol + 1; row[0] = 1; add_constraintex(lp, 1, row, colno, EQ, 0); //6. defined for each route segment (i, j) //if the segment (i, j) exists, then the time B_j // the taxi reaches j will be greater than // B_i + time(i, j) // (time is interchangeable with distance) //in other words, // B_j >= ( B_i + time(i, j) ) * x_ij // //**but that's non-linear (since B_i * x_ij) //to achieve the if statement, we subtract a large // number M from the right and M * x_ij on the left //the equation becomes: // B_j - B_i - M*x_ij >= time(i, j) - M // //m_ij that we found earlier is suitable for M, since // if x_ij = 0 the equation reduces to // B_j - B_i >= time(i, j) - M // >> M >= B_i + time(i, j) - B_j // we used the maximum possible value for B_i (latest[i]) // and the minimim for B_j (earliest[j]), so everything // is good :) for(int i = 0; i < points.size() + 1; i++) { for(int j = 0; j < points.size(); j++) { colno[0] = ncol + 1 + i; colno[1] = ncol + 1 + j + 1; //make sure to add an extra 1 because we're not including current location colno[2] = i * points.size() + j + 1; double constant = costMatrix[i][j] - m[i][j]; //only use positive constants or it seems to explode if(constant >= 0) { row[0] = -1; row[1] = 1; row[2] = -m[i][j]; add_constraintex(lp, 3, row, colno, GE, constant); } else { row[0] = 1; row[1] = -1; row[2] = m[i][j]; add_constraintex(lp, 3, row, colno, LE, -constant); } } } //constraints 7, 8, and 9 for(int i = 0; i < points.size(); i++) { if(points[i]->type == 1) { //dropoff point //make sure to add an extra 1 because we're not including current location colno[0] = ncol + 1 + i + 1; colno[1] = ncol + 1 + pairIndex[i] + 1; row[0] = 1; row[1] = -1; //constraints on L_i (= B_i - B_pickup[i]) //7. L_i >= time(pickup[i], i) add_constraintex(lp, 2, row, colno, GE, costMatrix[pairIndex[i] + 1][i]); //8. L_i <= remaining service constraint add_constraintex(lp, 2, row, colno, LE, points[i]->remaining); } else if(points[i]->type == 0 || points[i]->type == 2) { //pickup or stand-alone dropoff point colno[0] = ncol + 1 + i + 1; row[0] = 1; //9. B_i <= remaining pickup constraint add_constraintex(lp, 1, row, colno, LE, points[i]->remaining); } } //10. this used to enforce that all varibles be // non-negative, but it seems to be working now // (lpsolve makes variables non-negative unless // explicitly stated in a constraint) for(int i = ncol; i < ncol_total; i++) { colno[0] = i + 1; row[0] = 1; //add_constraintex(lp, 1, row, colno, GE, 0); } //disable rowmode because we're done building model set_add_rowmode(lp, FALSE); //objective function: minimize sum( time(i, j) * x_ij ) //we maximize the negative though // (we could change to set_minim(lp), but it's the same thing) for(int i = 0; i < points.size() + 1; i++) { for(int j = 0; j < points.size(); j++) { colno[i * points.size() + j] = i * points.size() + j + 1;; row[i * points.size() + j] = -costMatrix[i][j]; } } set_obj_fnex(lp, ncol, row, colno); set_maxim(lp); //maximize the objective function struct timeval solveStartTime; struct timeval solveEndTime; gettimeofday(&solveStartTime, NULL); int ret = solve(lp); gettimeofday(&solveEndTime, NULL); long tS = solveStartTime.tv_sec*1000000 + (solveStartTime.tv_usec); long tE = solveEndTime.tv_sec*1000000 + (solveEndTime.tv_usec); long solveTime = tE - tS; if(iteration == 0 && ret != TIMEOUT) { lpTotalTime += solveTime; if(solveTime > lpMaxTime) lpMaxTime = solveTime; lpNum++; cout << "lptimestatus: " << lpTotalTime / lpNum << " " << lpMaxTime << " " << lpNum << " " << solveTime << endl; } //if we didn't get the optimal solution, don't continue if(ret != OPTIMAL) { delete colno; delete row; delete_lp(lp); bestList.clear(); if(ret == TIMEOUT) { //if we timed out, then we need to try again cout << "timed out on iteration " << iteration << ", advancing..." << endl; continue; } else { return bestList; } } get_variables(lp, row); //store variables in our row array //extract the ordering of the points from the x_ij in the row //at the same time, we calculate the route's distance int previous = 0; minTour = 0; for(int i = 0; i < points.size(); i++) { for(int j = 0; j < points.size(); j++) { if(row[previous * points.size() + j] == 1) { minTour += costMatrix[previous][j]; bestList.push_back(points[j]); previous = j + 1; break; } } } delete colno; delete row; delete_lp(lp); //sometimes errors occur, probably because M was // too large and double-precision isn't accurate // enough //in these cases, since they're rare enough, we // assume that the model was infeasible if(bestList.size() != points.size()) { bestList.clear(); minTour = numeric_limits<double>::max(); return bestList; } return bestList; } }
int main(int argc, char* argv[]) { if(argc != 2) { std::cout << "Usage: " << argv[0] << " /path/to/lua/script.lua" << std::endl; exit(1); } std::cout.unsetf(std::ios::floatfield); std::cout.precision(5); std::cout << std::fixed; std::cout << "==================== SETUP ====================" << std::endl; // TODO: detect unusual currency bases for accurate profit calculation auto config = std::make_shared<LuaScript>(argv[1]); std::cout << "Simulating a maximum of " << config->steps() << " steps" << std::endl; std::cout << config->optimizations() << " optimizations per in sample" << std::endl; auto charts = Chart::load_from_string(config->charts()); auto ts = std::make_unique<TickSource>(config->csv_path()); auto vars = Variable::load_from_string(config->variables()); auto optimizer = std::make_unique<Optimizer>(vars); ts->fill_charts(charts); ts->advance_charts_to_next_sunday(charts); int step_number = 1; int weeks_in_sample = std::stoi(config->in_sample_time()); int weeks_out_of_sample = std::stoi(config->out_of_sample_time()); std::vector<float> optimization_scores; std::vector<float> execution_scores; // ----- MAIN LOOP ------------------------------------------------------------------------- for(;;) { // ----- FIND IN AND OUT OF SAMPLE START AND END POINTS ---------------------------- // in_sample_record_end is just out_of_sample_record_start - 1 unsigned long in_sample_record_start = ts->next_record_id(); unsigned long out_of_sample_record_start = 0; unsigned long out_of_sample_record_end = 0; bool tick_is_sunday = true; bool on_sunday = true; int sundays_seen = 0; for(auto tick = ts->next(); tick; tick = ts->next()) { tick_is_sunday = tick->is_sunday(); if(!on_sunday && tick_is_sunday) { on_sunday = true; sundays_seen++; } else if(on_sunday && !tick_is_sunday) { on_sunday = false; } if(sundays_seen == weeks_in_sample) { out_of_sample_record_start = ts->next_record_id() - 1; break; } } if(!out_of_sample_record_start) { bail("ran out of tick source when searching for out of sample start"); } sundays_seen = 0; on_sunday = true; for(auto tick = ts->next(); tick; tick = ts->next()) { tick_is_sunday = tick->is_sunday(); if(!on_sunday && tick_is_sunday) { on_sunday = true; sundays_seen++; } else if(on_sunday && !tick_is_sunday) { on_sunday = false; } if(sundays_seen == weeks_out_of_sample) { // stop on the tick before the current tick out_of_sample_record_end = ts->next_record_id() - 2; break; } } if(!out_of_sample_record_end) { bail("ran out of tick source when searching for out of sample end"); } std::cout << "In sample: " << ts->peek_at(in_sample_record_start)->show() << " through " << ts->peek_at(out_of_sample_record_start - 1)->show() << std::endl; std::cout << "Out of sample: " << ts->peek_at(out_of_sample_record_start)->show() << " through " << ts->peek_at(out_of_sample_record_end)->show() << std::endl; // ----- OPTIMIZE ON IN SAMPLE PERIOD ---------------------------------------------- auto subset = ts->subset(in_sample_record_start, out_of_sample_record_start - 1); auto winner = optimizer->optimize_variables_on(config, charts, subset); // optimizer->print_scores(); // ----- IF OPTIMIZATION SUCCEEDED, EXECUTE ON OUT OF SAMPLE PERIOD ---------------- if(winner->get_score() < config->minimum_optimization_score()) { bail("Failed to find a variables above the cutoff"); } optimization_scores.push_back(winner->get_score()); std::cout << "==================== EXECUTING ON ====================" << std::endl; std::cout << "Winning variables!" << std::endl; std::cout << "Score: " << winner->get_score() << std::endl; for(auto var: winner->get_variables()) { std::cout << "\t" << var->get_name() << " -> " << var->show() << std::endl; } auto new_vars = winner->get_variables(); auto new_config = config; auto new_charts = charts; auto oos = ts->subset(out_of_sample_record_start, out_of_sample_record_end); Simulation sim(new_config, new_charts, new_vars); sim.run(oos); std::cout << "Execution score: " << sim.get_score() << std::endl; std::cout << "% profitable: " << sim.percentage_of_profitable_trades() << "%" << std::endl; std::cout << "Average trade duration: " << sim.average_trade_duration() << std::endl; std::cout << "Worst DD: " << sim.get_worst_drawdown() << "%" << std::endl; std::cout << "Equity high: " << sim.get_equity_high() << std::endl; std::cout << "Equity low: " << sim.get_equity_low() << std::endl; std::cout << "Trades: " << sim.get_trade_count() << std::endl; std::cout << "Winners: " << sim.get_winning_trade_count() << std::endl; std::cout << "Losers: " << sim.get_losing_trade_count() << std::endl; std::cout << "Best: " << sim.best_winning_trade()->profit() << std::endl; std::cout << "Worst: " << sim.worst_losing_trade()->profit() << std::endl; // ----- IF EXECUTION SUCCEEDED, RECORD RESULTS ------------------------------------ if(sim.get_score() < config->minimum_execution_score()) { bail("Failed at optimization step"); } execution_scores.push_back(sim.get_score()); // ----- EXIT IF WE'RE AT MAX STEPS ------------------------------------------------ step_number++; if(step_number > config->steps()) { std::cout << "Reached max steps, breaking" << std::endl; break; } // ----- ADVANCE CHARTS TO NEXT IN SAMPLE START ------------------------------------ ts->seek_to_record(in_sample_record_start); ts->advance_charts_to_next_sunday(charts); } std::cout << "==================== RESULTS ====================" << std::endl; // ----- SHOW PROFIT FOR EACH PERIOD ------------------------------------------------------- std::cout << "Scores:" << std::endl; for(unsigned long i = 0; i < optimization_scores.size(); i++) { std::cout << i + 1 << " - "; std::cout << "Opti: " << optimization_scores[i]; std::cout << " - "; std::cout << "Exec: " << execution_scores[i]; std::cout << std::endl; } // ----- SHOW WALK FORWARD EFFICIENCY ------------------------------------------------------ float optimization_total = sum_vector(optimization_scores); float execution_total = sum_vector(execution_scores); float efficiency = execution_total / optimization_total; std::cout << "Optimization total: " << optimization_total << " - "; std::cout << "Execution total: " << execution_total << " - "; std::cout << "WFA efficiency: " << efficiency << "% - Verdict: "; if(efficiency < 0.5) { std::cout << "FAIL"; } else if(efficiency >= 0.5 && efficiency < 1.0) { std::cout << "ACCEPTABLE"; } else if(efficiency >= 1.0 && efficiency <= 1.5) { std::cout << "GREAT"; } else { std::cout << "TOO GOOD - SUSPICIOUS"; } std::cout << std::endl; // ----- SHOW PROFIT FACTOR ---------------------------------------------------------------- float gross_profit = 0.0; float gross_loss = 0.0; for(auto score: execution_scores) { if(score >= 0.0) gross_profit += score; else gross_loss += score; } gross_loss = std::abs(gross_loss); float profit_factor = gross_profit / gross_loss; std::cout << "Gross profit: " << gross_profit << " - "; std::cout << "Gross loss: " << gross_loss << " - "; std::cout << "Profit factor: " << profit_factor << " - Verdict: "; if(profit_factor < 1.5) { std::cout << "FAIL"; } else if(profit_factor >= 1.5 && profit_factor < 2.0) { std::cout << "ACCEPTABLE"; } else if(profit_factor >= 2.0 && profit_factor <= 3.0) { std::cout << "GREAT"; } else { std::cout << "TOO GOOD - SUSPICIOUS"; } std::cout << std::endl; // ----- SHOW FINAL SCORE ------------------------------------------------------------------ // TODO: final score should be some function of two or more of the following: // execution_total, WFA efficiency, max drawdown, profit factor, % profitable std::cout << "Final score: " << execution_total << " - Minimum score: " << config->minimum_overall_score() << " - Verdict: "; std::cout << (execution_total >= config->minimum_overall_score() ? "PASS" : "FAIL") << std::endl; std::cout << "==================== SHUTDOWN ====================" << std::endl; return 0; }
int l1_logreg_train(dmatrix *X, double *b, double lambda, train_opts to, double *initial_x, double *initial_t, double *sol, int *total_ntiter, int *total_pcgiter) { /* problem data */ problem_data_t prob; variables_t vars; dmatrix *matX1; /* matX1 = diag(b)*X_std */ dmatrix *matX2; /* matX2 = X_std.^2 (only for pcg) */ double *ac, *ar; double *avg_x, *std_x; int m, n, ntiter, pcgiter, status; double pobj, dobj, gap; double t, s, maxAnu; double *g, *h, *z, *expz, *expmz; double *x, *v, *w, *u; double *dx, *dv, *dw, *du; double *gv, *gw, *gu, *gx; double *d1, *d2, *Aw; /* pcg variables */ pcg_status_t pcgstat; adata_t adata; mdata_t mdata; double *precond; /* temporary variables */ double *tm1, *tn1, *tn2, *tn3, *tn4, *tx1; /* temporary variables for dense case (cholesky) */ dmatrix *B; /* m x n (or m x n) */ dmatrix *BB; /* n x n (or m x m) */ char format_buf[PRINT_BUF_SIZE]; #if INTERNAL_PLOT dmatrix *internal_plot; dmat_new_dense(&internal_plot, 3, MAX_NT_ITER); memset(internal_plot->val,0,sizeof(double)*3*MAX_NT_ITER); /* row 1: cum_nt_iter, row 2: cum_pcg_iter, row 3: duality gap */ #endif p2func_progress print_progress = NULL; /* * INITIALIZATION */ s = 1.0; pobj = DBL_MAX; dobj = -DBL_MAX; pcgiter = 0; matX1 = NULL; matX2 = NULL; init_pcg_status(&pcgstat); dmat_duplicate(X, &matX1); dmat_copy(X, matX1); m = matX1->m; n = matX1->n; if (to.sflag == TRUE) { /* standardize_data not only standardizes the data, but also multiplies diag(b). */ standardize_data(matX1, b, &avg_x, &std_x, &ac, &ar); } else { /* matX1 = diag(b)*X */ dmat_diagscale(matX1, b, FALSE, NULL, TRUE); avg_x = std_x = ac = ar = NULL; } if (matX1->nz >= 0) /* only for pcg */ { dmat_elemAA(matX1, &matX2); } else { matX2 = NULL; } set_problem_data(&prob, matX1, matX2, ac, ar, b, lambda, avg_x, std_x); create_variables(&vars, m, n); get_variables(&vars, &x, &v, &w, &u, &dx, &dv, &dw, &du, &gx, &gv, &gw, &gu, &g, &h, &z, &expz, &expmz, &d1, &d2, &Aw); allocate_temporaries(m, n, (matX1->nz >= 0), &tm1, &tn1, &tn2, &tn3, &tn4, &tx1, &precond, &B, &BB); if (initial_x == NULL) { dmat_vset(1, 0.0, v); dmat_vset(n, 0.0, w); dmat_vset(n, 1.0, u); dmat_vset(n+n+1, 0, dx); t = min(max(1.0, 1.0 / lambda), 2.0 * n / ABSTOL); } else { dmat_vcopy(n+n+1, initial_x, x); dmat_vset(n+n+1, 0, dx); t = *initial_t; } set_adata(&adata, matX1, ac, ar, b, h, d1, d2); set_mdata(&mdata, m, n, precond); /* select printing function and format according to verbose level and method type (pcg/direct) */ if (to.verbose_level>=2) init_progress((matX1->nz >= 0), to.verbose_level, format_buf, &print_progress); /*** MAIN LOOP ************************************************************/ for (ntiter = 0; ntiter < MAX_NT_ITER; ntiter++) { /* * Sets v as the optimal value of the intercept. */ dmat_yAmpqx(matX1, ac, ar, w, Aw); optimize_intercept(v, z, expz, expmz, tm1, b, Aw, m); /* * Constructs dual feasible point nu. */ fprimes(m, expz, expmz, g, h); /* partially computes the gradient of phi. the rest part of the gradient will be completed while computing the search direction. */ gv[0] = dmat_dot(m, b, g); /* gv = b'*g */ dmat_yAmpqTx(matX1, ac, ar, g, gw); /* gw = A'*g */ dmat_waxpby(m, -1, g, 0, NULL, tm1); /* nu = -g */ maxAnu = dmat_norminf(n, gw); /* max(A'*nu) */ if (maxAnu > lambda) dmat_waxpby(m, lambda / maxAnu, tm1, 0.0, NULL, tm1); /* * Evaluates duality gap. */ pobj = logistic_loss2(m,z,expz,expmz)/m + lambda*dmat_norm1(n,w); dobj = max(nentropy(m, tm1) / m, dobj); gap = pobj - dobj; #if INTERNAL_PLOT internal_plot->val[0*MAX_NT_ITER+ntiter] = (double)ntiter; internal_plot->val[1*MAX_NT_ITER+ntiter] = (double)pcgiter; internal_plot->val[2*MAX_NT_ITER+ntiter] = gap; #endif if (to.verbose_level>=2) { (*print_progress)(format_buf, ntiter, gap, pobj, dobj, s, t, pcgstat.flag, pcgstat.relres, pcgstat.iter); } /* * Quits if gap < tolerance. */ if (gap < to.tolerance ) /***********************************************/ { if (sol != NULL) { /* trim solution */ int i; double lambda_threshold; lambda_threshold = to.ktolerance*lambda; sol[0] = x[0]; for (i = 0; i < n; i++) { sol[i+1] = (fabs(gw[i])>lambda_threshold)? x[i+1] : 0.0; } /* if standardized, sol = coeff/std */ if (to.sflag == TRUE && to.cflag == FALSE) { dmat_elemdivi(n, sol+1, std_x, sol+1); sol[0] -= dmat_dot(n, avg_x, sol+1); } } if (initial_x != NULL) { dmat_vcopy(n+n+1, x, initial_x); *initial_t = t; } if (total_pcgiter) *total_pcgiter = pcgiter; if (total_ntiter ) *total_ntiter = ntiter; /* free memory */ free_variables(&vars); free_temporaries(tm1, tn1, tn2, tn3, tn4, tx1, precond, B, BB); free_problem_data(&prob); #if INTERNAL_PLOT write_mm_matrix("internal_plot",internal_plot,"",TYPE_G); #endif return STATUS_SOLUTION_FOUND; } /********************************************************************/ /* * Updates t */ if (s >= 0.5) { t = max(min(2.0 * n * MU / gap, MU * t), t); } else if (s < 1e-5) { t = 1.1*t; } /* * Computes search direction. */ if (matX1->nz >= 0) { /* pcg */ compute_searchdir_pcg(&prob, &vars, t, s, gap, &pcgstat, &adata, &mdata, precond, tm1, tn1, tx1); pcgiter += pcgstat.iter; } else { /* direct */ if (n > m) { /* direct method for n > m, SMW */ compute_searchdir_chol_fat(&prob, &vars, t, B, BB, tm1, tn1, tn2, tn3, tn4); } else { /* direct method for n <= m */ compute_searchdir_chol_thin(&prob, &vars, t, B, BB, tm1, tn1, tn2); } } /* * Backtracking linesearch & update x = (v,w,u) and z. */ s = backtracking_linesearch(&prob, &vars, t, tm1, tx1); if (s < 0) break; /* BLS error */ } /*** END OF MAIN LOOP *****************************************************/ /* Abnormal termination */ if (s < 0) { status = STATUS_MAX_LS_ITER_EXCEEDED; } else /* if (ntiter == MAX_NT_ITER) */ { status = STATUS_MAX_NT_ITER_EXCEEDED; } if (sol != NULL) { /* trim solution */ int i; double lambda_threshold; lambda_threshold = to.ktolerance*lambda; sol[0] = x[0]; for (i = 0; i < n; i++) { sol[i+1] = (fabs(gw[i])>lambda_threshold)? x[i+1] : 0.0; } /* if standardized, sol = coeff/std */ if (to.sflag == TRUE && to.cflag == FALSE) { dmat_elemdivi(n, sol+1, std_x, sol+1); sol[0] -= dmat_dot(n, avg_x, sol+1); } } if (initial_x != NULL) { dmat_vcopy(n+n+1, x, initial_x); *initial_t = t; } if (total_pcgiter) *total_pcgiter = pcgiter; if (total_ntiter ) *total_ntiter = ntiter; /* free memory */ free_variables(&vars); free_temporaries(tm1, tn1, tn2, tn3, tn4, tx1, precond, B, BB); free_problem_data(&prob); #if INTERNAL_PLOT write_mm_matrix("internal_plot",internal_plot,"",TYPE_G); #endif return status; }