Exemple #1
0
static PyObject* Bar_getspecvarvalm(BarObject *self,
				    double(*valfuncs[])(glp_prob*, int)) {
  if (!Bar_Valid(self, 1)) return NULL;
  if (glp_get_num_int(LP) == 0) {
    PyErr_SetString(PyExc_TypeError,
		    "MIP values require mixed integer problem");
    return NULL;
  }
  double(*valfunc)(glp_prob*, int) = valfuncs[Bar_Row(self) ? 1 : 0];
  return PyFloat_FromDouble(valfunc(LP, Bar_Index(self)+1));
}
Exemple #2
0
static PyObject* Bar_getvarval(BarObject *self, void *closure) {
  if (!Bar_Valid(self, 1)) return NULL;
  // Compute what we need to index to get the appropriate function pointer.
  int isrow = Bar_Row(self) ? 1 : 0;
  int isdual = closure==NULL ? 0 : 1;
  int last = self->py_bc->py_lp->last_solver;
  if (last < 0) last = 0; // If no solver called yet, assume simplex is OK.
  if (last > 2) {
    PyErr_Format(PyExc_RuntimeError,
		 "bad internal state for last solver identifier: %d", last);
    return NULL;
  }
  // Get and verify that function pointer.
  double(*valfunc)(glp_prob*,int) =
    rowcol_primdual_funcptrs[last*4 + isdual*2 + isrow];
  if (valfunc==NULL) {
    PyErr_SetString(PyExc_RuntimeError,
		    "dual values do not exist for MIP solver");
    return NULL;
  }
  // Get whatever sort of variable this is and return it.
  return PyFloat_FromDouble(valfunc(LP, Bar_Index(self)+1));
}
Exemple #3
0
static PyObject* Bar_getspecvarval(BarObject *self,
				   double(*valfuncs[])(glp_prob*, int)) {
  if (!Bar_Valid(self, 1)) return NULL;
  double(*valfunc)(glp_prob*, int) = valfuncs[Bar_Row(self) ? 1 : 0];
  return PyFloat_FromDouble(valfunc(LP, Bar_Index(self)+1));
}
Exemple #4
0
Fichier : pcln.c Projet : 8l/go
// funcpctab writes to dst a pc-value table mapping the code in func to the values
// returned by valfunc parameterized by arg. The invocation of valfunc to update the
// current value is, for each p,
//
//	val = valfunc(func, val, p, 0, arg);
//	record val as value at p->pc;
//	val = valfunc(func, val, p, 1, arg);
//
// where func is the function, val is the current value, p is the instruction being
// considered, and arg can be used to further parameterize valfunc.
static void
funcpctab(Link *ctxt, Pcdata *dst, LSym *func, char *desc, int32 (*valfunc)(Link*, LSym*, int32, Prog*, int32, void*), void* arg)
{
	int dbg, i;
	int32 oldval, val, started;
	uint32 delta;
	vlong pc;
	Prog *p;

	// To debug a specific function, uncomment second line and change name.
	dbg = 0;
	//dbg = strcmp(func->name, "main.main") == 0;
	//dbg = strcmp(desc, "pctofile") == 0;

	ctxt->debugpcln += dbg;

	dst->n = 0;

	if(ctxt->debugpcln)
		Bprint(ctxt->bso, "funcpctab %s [valfunc=%s]\n", func->name, desc);

	val = -1;
	oldval = val;
	if(func->text == nil) {
		ctxt->debugpcln -= dbg;
		return;
	}

	pc = func->text->pc;
	
	if(ctxt->debugpcln)
		Bprint(ctxt->bso, "%6llux %6d %P\n", pc, val, func->text);

	started = 0;
	for(p=func->text; p != nil; p = p->link) {
		// Update val. If it's not changing, keep going.
		val = valfunc(ctxt, func, val, p, 0, arg);
		if(val == oldval && started) {
			val = valfunc(ctxt, func, val, p, 1, arg);
			if(ctxt->debugpcln)
				Bprint(ctxt->bso, "%6llux %6s %P\n", (vlong)p->pc, "", p);
			continue;
		}

		// If the pc of the next instruction is the same as the
		// pc of this instruction, this instruction is not a real
		// instruction. Keep going, so that we only emit a delta
		// for a true instruction boundary in the program.
		if(p->link && p->link->pc == p->pc) {
			val = valfunc(ctxt, func, val, p, 1, arg);
			if(ctxt->debugpcln)
				Bprint(ctxt->bso, "%6llux %6s %P\n", (vlong)p->pc, "", p);
			continue;
		}

		// The table is a sequence of (value, pc) pairs, where each
		// pair states that the given value is in effect from the current position
		// up to the given pc, which becomes the new current position.
		// To generate the table as we scan over the program instructions,
		// we emit a "(value" when pc == func->value, and then
		// each time we observe a change in value we emit ", pc) (value".
		// When the scan is over, we emit the closing ", pc)".
		//
		// The table is delta-encoded. The value deltas are signed and
		// transmitted in zig-zag form, where a complement bit is placed in bit 0,
		// and the pc deltas are unsigned. Both kinds of deltas are sent
		// as variable-length little-endian base-128 integers,
		// where the 0x80 bit indicates that the integer continues.

		if(ctxt->debugpcln)
			Bprint(ctxt->bso, "%6llux %6d %P\n", (vlong)p->pc, val, p);

		if(started) {
			addvarint(ctxt, dst, (p->pc - pc) / ctxt->arch->minlc);
			pc = p->pc;
		}
		delta = val - oldval;
		if(delta>>31)
			delta = 1 | ~(delta<<1);
		else
			delta <<= 1;
		addvarint(ctxt, dst, delta);
		oldval = val;
		started = 1;
		val = valfunc(ctxt, func, val, p, 1, arg);
	}