Skip to content

Instantly share code, notes, and snippets.

@hsa-online
Created November 10, 2016 16:19
Show Gist options
  • Save hsa-online/bd69ddb7147eb20d55ce7fc95faa80d5 to your computer and use it in GitHub Desktop.
Save hsa-online/bd69ddb7147eb20d55ce7fc95faa80d5 to your computer and use it in GitHub Desktop.
This test causes "Assertion failed at amoeba.h line 935" in the "https://github.com/starwing/amoeba" library
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define AM_IMPLEMENTATION
#include "amoeba.h"
#define UNUSED(x) (void)(x)
static size_t allmem = 0;
static size_t maxmem = 0;
static void *debug_allocf(void *ud, void *ptr, size_t ns, size_t os) {
UNUSED(ud);
void *newptr = NULL;
allmem += ns;
allmem -= os;
if (maxmem < allmem) maxmem = allmem;
if (ns == 0) free(ptr);
else {
newptr = realloc(ptr, ns);
if (newptr == NULL)
printf("NO memory!\n"); //longjmp(jbuf, 1);
}
#ifdef DEBUG_MEMORY
printf("new(%p):\t+%d, old(%p):\t-%d\n", newptr, (int)ns, ptr, (int)os);
#endif
return newptr;
}
static void am_dumpkey(am_Symbol sym) {
int ch = 'v';
switch (sym.type) {
case AM_EXTERNAL: ch = 'v'; break;
case AM_SLACK: ch = 's'; break;
case AM_ERROR: ch = 'e'; break;
case AM_DUMMY: ch = 'd'; break;
}
printf("%c%d", ch, (int)sym.id);
}
static void am_dumprow(am_Row *row) {
am_Term *term = NULL;
printf("%g", row->constant);
while (am_nextentry(&row->terms, (am_Entry**)&term)) {
double multiplier = term->multiplier;
printf(" %c ", multiplier > 0.0 ? '+' : '-');
if (multiplier < 0.0) multiplier = -multiplier;
if (!am_approx(multiplier, 1.0))
printf("%g*", multiplier);
am_dumpkey(am_key(term));
}
printf("\n");
}
static void am_dumpsolver(am_Solver *solver) {
am_Row *row = NULL;
int idx = 0;
printf("-------------------------------\n");
printf("solver: ");
am_dumprow(&solver->objective);
printf("rows(%d):\n", (int)solver->rows.count);
while (am_nextentry(&solver->rows, (am_Entry**)&row)) {
printf("%d. ", ++idx);
am_dumpkey(am_key(row));
printf(" = ");
am_dumprow(row);
}
printf("-------------------------------\n");
}
int main() {
am_Variable *arrX[1024], *arrY[1024];
// Create set of rules to distribute vertexes of a binary tree like this one:
// 0
// / \
// / \
// 1 2
// / \ / \
// 3 4 5 6
am_Solver *pSolver = am_newsolver(debug_allocf, NULL);
// Xroot=500, Yroot=10
arrX[0] = am_newvariable(pSolver);
arrY[0] = am_newvariable(pSolver);
am_addedit(pSolver, arrX[0], AM_STRONG);
am_addedit(pSolver, arrY[0], AM_STRONG);
am_suggest(pSolver, arrX[0], 500.0);
am_suggest(pSolver, arrY[0], 10.0);
int nCurrentRowPointsCount = 1;
int nCurrentRowFirstPointIndex = 0;
am_Constraint *pC;
int nResult;
int nRows = 3;
for (int nRow = 1; nRow < nRows; nRow++) {
int nPreviousRowFirstPointIndex = nCurrentRowFirstPointIndex;
int nParentPoint = 0;
nCurrentRowFirstPointIndex += nCurrentRowPointsCount;
nCurrentRowPointsCount *= 2;
for (int nPoint = 0; nPoint < nCurrentRowPointsCount; nPoint++) {
arrX[nCurrentRowFirstPointIndex + nPoint] = am_newvariable(pSolver);
arrY[nCurrentRowFirstPointIndex + nPoint] = am_newvariable(pSolver);
// Ycur = Yprev_row + 10
pC = am_newconstraint(pSolver, AM_REQUIRED);
am_addterm(pC, arrY[nCurrentRowFirstPointIndex + nPoint], 1.0);
am_setrelation(pC, AM_EQUAL);
am_addterm(pC, arrY[nCurrentRowFirstPointIndex - 1], 1.0);
am_addconstant(pC, 10.0);
nResult = am_add(pSolver, pC);
assert(nResult == AM_OK);
if (nPoint > 0) {
// Xcur = XPrev + 10
pC = am_newconstraint(pSolver, AM_REQUIRED);
am_addterm(pC, arrX[nCurrentRowFirstPointIndex + nPoint], 1.0);
am_setrelation(pC, AM_EQUAL);
am_addterm(pC, arrX[nCurrentRowFirstPointIndex + nPoint - 1], 1.0);
am_addconstant(pC, 10.0);
nResult = am_add(pSolver, pC);
assert(nResult == AM_OK);
}
// 3rd call of this "if" causes "Unsatisfied" constraint and
// "Assertion failed at amoeba.h line 935"
if ((nPoint % 2) == 1) {
// Xparent = 0.5 * Xcur + 0.5 * Xprev
pC = am_newconstraint(pSolver, AM_REQUIRED);
am_addterm(pC, arrX[nPreviousRowFirstPointIndex + nParentPoint], 1.0);
am_setrelation(pC, AM_EQUAL);
am_addterm(pC, arrX[nCurrentRowFirstPointIndex + nPoint], 0.5);
am_addterm(pC, arrX[nCurrentRowFirstPointIndex + nPoint - 1], 0.5);
nResult = am_add(pSolver, pC);
assert(nResult == AM_OK);
nParentPoint++;
}
}
/* // By uncommenting this code it's possible to make correct constraints
// X0 = 0.5 * Xrightmost + 0.5 * Xleftmost
pC = am_newconstraint(pSolver, AM_REQUIRED);
am_addterm(pC, arrX[0], 1.0);
am_setrelation(pC, AM_EQUAL);
am_addterm(pC, arrX[nCurrentRowFirstPointIndex + nCurrentRowPointsCount - 1], 0.5);
am_addterm(pC, arrX[nCurrentRowFirstPointIndex], 0.5);
nResult = am_add(pSolver, pC);
assert(nResult == AM_OK);
*/
}
//am_dumpsolver(pSolver);
int nLastPointIndex = nCurrentRowFirstPointIndex + nCurrentRowPointsCount - 1;
for (int i = 0; i <= nLastPointIndex; i++) {
printf("Point %d: (%f, %f)\n", i, am_value(arrX[i]), am_value(arrY[i]));
}
am_delsolver(pSolver);
printf("allmem = %d\n", (int)allmem);
printf("maxmem = %d\n", (int)maxmem);
assert(allmem == 0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment