double residual(mlcore::Problem* problem, mlcore::State* s) { mlcore::Action* bestAction = greedyAction(problem, s); if (bestAction == nullptr) return 0.0; // state is a dead-end, nothing to do here double res = qvalue(problem, s, bestAction) - s->cost(); return fabs(res); }
mlcore::Action* greedyAction(mlcore::Problem* problem, mlcore::State* s) { if (s->bestAction() != nullptr) return s->bestAction(); mlcore::Action* bestAction = nullptr; double bestQ = mdplib::dead_end_cost; bool hasAction = false; for (mlcore::Action* a : problem->actions()) { if (!problem->applicable(s, a)) continue; hasAction = true; double qAction = std::min(mdplib::dead_end_cost, qvalue(problem, s, a)); if (qAction <= bestQ) { bestQ = qAction; bestAction = a; } } if (!hasAction) s->markDeadEnd(); return bestAction; }
double AODetHeuristic::AODetBellmanUpdate(mlcore::State* s) { double bestQ = aodet_->goal(s) ? 0.0 : mdplib::dead_end_cost; bool hasAction = false; mlcore::Action* bestAction = nullptr; for (mlcore::Action* a : aodet_->actions(s)) { if (!aodet_->applicable(s, a)) continue; hasAction = true; double qAction = std::min(mdplib::dead_end_cost, qvalue(aodet_, s, a)); if (qAction <= bestQ) { bestQ = qAction; bestAction = a; } } if (!hasAction && bestQ >= mdplib::dead_end_cost) s->markDeadEnd(); double residual = s->cost() - bestQ; s->setCost(bestQ); s->setBestAction(bestAction); return fabs(residual); }
std::pair<double, mlcore::Action*> bellmanBackup(mlcore::Problem* problem, mlcore::State* s) { double bestQ = problem->goal(s) ? 0.0 : mdplib::dead_end_cost; bool hasAction = false; mlcore::Action* bestAction = nullptr; for (mlcore::Action* a : problem->actions()) { if (!problem->applicable(s, a)) continue; hasAction = true; double qAction = std::min(mdplib::dead_end_cost, qvalue(problem, s, a)); if (qAction <= bestQ) { bestQ = qAction; bestAction = a; } } if (!hasAction && bestQ >= mdplib::dead_end_cost) s->markDeadEnd(); return std::make_pair(bestQ, bestAction); }
char *look_in_lisp_variable(char *o, int prefix) { Lisp_Object nil, var; /* * I will start by tagging a '$' (or whatever) on in front of the * parameter name. */ o[0] = (char)prefix; var = make_undefined_symbol(o); nil = C_nil; /* * make_undefined_symbol() could fail either if we had utterly run out * of memory or if somebody generated an interrupt (eg ^C) around now. Ugh. */ if (exception_pending()) { flip_exception(); return NULL; } /* * If the variable $name was undefined then I use an empty replacement * text for it. Otherwise I need to look harder at its value. */ if (qvalue(var) == unset_var) return o; else { Header h; intptr_t len; var = qvalue(var); /* * Mostly I expect that the value will be a string or symbol. */ #ifdef COMMON if (complex_stringp(var)) { var = simplify_string(var); nil = C_nil; if (exception_pending()) { flip_exception(); return NULL; } } #endif /* COMMON */ if (symbolp(var)) { var = get_pname(var); nil = C_nil; if (exception_pending()) { flip_exception(); return NULL; } h = vechdr(var); } else if (!is_vector(var) || type_of_header(h = vechdr(var)) != TYPE_STRING) return NULL; len = length_of_header(h) - CELL; /* * Copy the characters from the string or from the name of the variable * into the file-name buffer. There could at present be a crash here * if the expansion was very very long and overflowed my buffer. Tough * luck for now - people doing that (maybe) get what they (maybe) deserve. */ memcpy(o, (char *)var + (CELL - TAG_VECTOR), (size_t)len); o = o + len; return o; } }
void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, StkId res, TMS event) { TMS op = event; const StkId rb = p1; const StkId rc = p2; StkId ra = res; if (ttisvector2(rb) && ttisvector2(rc)) { lua_Float4 nb = v2value(rb), nc = v2value(rc); lua_Float4 r; switch (op) { case TM_ADD: PW2(addf); break; case TM_SUB: PW2(subf); break; case TM_MUL: PW2(mulf); break; case TM_DIV: if (nc.x==0.0 || nc.y==0.0) { luaG_runerror(L, "division by zero"); } PW2(divf); break; case TM_MOD: PW2(fmodf); break; case TM_POW: PW2(powf); break; case TM_UNM: r.x = -nb.x; r.y = -nb.y; break; default: lua_assert(0); break; } setv2value(ra, r); return; } else if (ttisvector3(rb) && ttisvector3(rc)) { lua_Float4 nb = v3value(rb), nc = v3value(rc); lua_Float4 r; switch (op) { case TM_ADD: PW3(addf); break; case TM_SUB: PW3(subf); break; case TM_MUL: PW3(mulf); break; case TM_DIV: if (nc.x==0.0 || nc.y==0.0 || nc.z==0.0) { luaG_runerror(L, "division by zero"); } PW3(divf); break; case TM_MOD: PW3(fmodf); break; case TM_POW: PW3(powf); break; case TM_UNM: r.x = -nb.x; r.y = -nb.y; r.z = -nb.z; break; default: lua_assert(0); break; } setv3value(ra, r); return; } else if (ttisvector4(rb) && ttisvector4(rc)) { lua_Float4 nb = v4value(rb), nc = v4value(rc); lua_Float4 r; switch (op) { case TM_ADD: PW4(addf); break; case TM_SUB: PW4(subf); break; case TM_MUL: PW4(mulf); break; case TM_DIV: if (nc.x==0.0 || nc.y==0.0 || nc.z==0.0 || nc.w==0.0) { luaG_runerror(L, "division by zero"); } PW4(divf); break; case TM_MOD: PW4(fmodf); break; case TM_POW: PW4(powf); break; case TM_UNM: r.x = -nb.x; r.y = -nb.y; r.z = -nb.z; r.w = -nb.w; break; default: lua_assert(0); break; } setv4value(ra, r); return; } else if (ttisvector2(rb) && ttisnumber(rc)) { lua_Float4 nb = v2value(rb); float nc = (float)nvalue(rc); lua_Float4 r; switch (op) { case TM_MUL: SCALAR2(mulf); break; case TM_ADD: SCALAR2(addf); break; case TM_SUB: SCALAR2(subf); break; case TM_DIV: if (nc==0.0) { luaG_runerror(L, "division by zero"); } SCALAR2(divf); break; case TM_MOD: SCALAR2(fmodf); break; case TM_POW: SCALAR2(powf); break; default: luaG_runerror(L, "Cannot use that op with vector2 and number"); } setv2value(ra, r); return; } else if (ttisvector3(rb) && ttisnumber(rc)) { lua_Float4 nb = v3value(rb); float nc = (float)nvalue(rc); lua_Float4 r; switch (op) { case TM_MUL: SCALAR3(mulf); break; case TM_ADD: SCALAR3(addf); break; case TM_SUB: SCALAR3(subf); break; case TM_DIV: if (nc==0.0) { luaG_runerror(L, "division by zero"); } SCALAR3(divf); break; case TM_MOD: SCALAR3(fmodf); break; case TM_POW: SCALAR3(powf); break; default: luaG_runerror(L, "Cannot use that op with vector3 and number"); } setv3value(ra, r); return; } else if (ttisvector4(rb) && ttisnumber(rc)) { lua_Float4 nb = v4value(rb); float nc = (float)nvalue(rc); lua_Float4 r; switch (op) { case TM_MUL: SCALAR4(mulf); break; case TM_ADD: SCALAR4(addf); break; case TM_SUB: SCALAR4(subf); break; case TM_DIV: if (nc==0.0) { luaG_runerror(L, "division by zero"); } SCALAR4(divf); break; case TM_MOD: SCALAR4(fmodf); break; case TM_POW: SCALAR4(powf); break; default: luaG_runerror(L, "Cannot use that op with vector4 and number"); } setv4value(ra, r); return; } else if (ttisnumber(rb) && ttisvector2(rc)) { lua_Float4 nb = v2value(rc); float nc = (float)nvalue(rb); lua_Float4 r; switch (op) { case TM_MUL: SCALAR2B(mulf); break; case TM_ADD: SCALAR2B(addf); break; case TM_SUB: SCALAR2B(subf); break; case TM_DIV: if (nb.x==0.0 || nb.y==0.0) { luaG_runerror(L, "division by zero"); } SCALAR2B(divf); break; case TM_POW: SCALAR2B(powf); break; default: luaG_runerror(L, "Cannot use that op with number and vector2"); } setv2value(ra, r); return; } else if (ttisnumber(rb) && ttisvector3(rc)) { lua_Float4 nb = v3value(rc); float nc = (float)nvalue(rb); lua_Float4 r; switch (op) { case TM_MUL: SCALAR3B(mulf); break; case TM_ADD: SCALAR3B(addf); break; case TM_SUB: SCALAR3B(subf); break; case TM_DIV: if (nb.x==0.0 || nb.y==0.0 || nb.z==0.0) { luaG_runerror(L, "division by zero"); } SCALAR3B(divf); break; case TM_POW: SCALAR3B(powf); break; default: luaG_runerror(L, "Cannot use that op with number and vector3"); } setv3value(ra, r); return; } else if (ttisnumber(rb) && ttisvector4(rc)) { lua_Float4 nb = v4value(rc); float nc = (float)nvalue(rb); lua_Float4 r; switch (op) { case TM_MUL: SCALAR4B(mulf); break; case TM_ADD: SCALAR4B(addf); break; case TM_SUB: SCALAR4B(subf); break; case TM_DIV: if (nb.x==0.0 || nb.y==0.0 || nb.z==0.0 || nb.w==0.0) { luaG_runerror(L, "division by zero"); } SCALAR4B(divf); break; case TM_POW: SCALAR4B(powf); break; default: luaG_runerror(L, "Cannot use that op with number and vector4"); } setv4value(ra, r); return; } else if (ttisquat(rb) && ttisquat(rc)) { lua_Float4 nb = qvalue(rb), nc = qvalue(rc); lua_Float4 r; switch (op) { case TM_MUL: r.w = nb.w*nc.w - nb.x*nc.x - nb.y*nc.y - nb.z*nc.z; r.x = nb.w*nc.x + nb.x*nc.w + nb.y*nc.z - nb.z*nc.y; r.y = nb.w*nc.y + nb.y*nc.w + nb.z*nc.x - nb.x*nc.z; r.z = nb.w*nc.z + nb.z*nc.w + nb.x*nc.y - nb.y*nc.x; break; default: luaG_runerror(L, "Cannot use that op with quat and quat"); } setqvalue(ra, r); return; } else if (ttisquat(rb) && ttisvector3(rc)) { lua_Float4 nb = qvalue(rb), nc = v3value(rc); lua_Float4 r; switch (op) { case TM_MUL: { float a=nb.w, b=nb.x, c=nb.y, d=nb.z; float mat[3][3] = { /* row major */ { a*a+b*b-c*c-d*d, 2*b*c-2*a*d , 2*b*d+2*a*c }, { 2*b*c+2*a*d , a*a-b*b+c*c-d*d, 2*c*d-2*a*b }, { 2*b*d-2*a*c , 2*c*d+2*a*b , a*a-b*b-c*c+d*d }, }; r.x = mat[0][0]*nc.x + mat[0][1]*nc.y + mat[0][2]*nc.z; r.y = mat[1][0]*nc.x + mat[1][1]*nc.y + mat[1][2]*nc.z; r.z = mat[2][0]*nc.x + mat[2][1]*nc.y + mat[2][2]*nc.z; } break; default: luaG_runerror(L, "Cannot use that op with quat and vector3"); } setv3value(ra, r); return; } if (!luaT_callbinTM(L, p1, p2, res, event)) { switch (event) { case TM_CONCAT: luaG_concaterror(L, p1, p2); /* call never returns, but to avoid warnings: *//* FALLTHROUGH */ case TM_BAND: case TM_BOR: case TM_BXOR: case TM_SHL: case TM_SHR: case TM_BNOT: { lua_Number dummy; if (tonumber(p1, &dummy) && tonumber(p2, &dummy)) luaG_tointerror(L, p1, p2); else luaG_opinterror(L, p1, p2, "perform bitwise operation on"); } /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ default: luaG_opinterror(L, p1, p2, "perform arithmetic on"); } } }