Skip to content

Commit

Permalink
working on replacing .expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
skeating committed Jan 4, 2025
1 parent 6a03580 commit 17a80dd
Show file tree
Hide file tree
Showing 4 changed files with 307 additions and 24 deletions.
91 changes: 71 additions & 20 deletions src/sbml/conversion/ExpressionAnalyser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,19 @@ using namespace std;

LIBSBML_CPP_NAMESPACE_BEGIN


bool compareExpressions(SubstitutionValues_t* values1, SubstitutionValues_t* values2)
struct compareExpressions
{
if (values1->type <= values2->type)
return true;
return false;
}
bool operator() (SubstitutionValues_t* values1, SubstitutionValues_t* values2)
{
if (values1 == NULL || values2 == NULL)
return false;
if (values1->type == TYPE_UNKNOWN || values2->type == TYPE_UNKNOWN)
return false;
if (values1->type < values2->type)
return true;
return false;
}
};

ExpressionAnalyser::ExpressionAnalyser()
: mModel (NULL),
Expand Down Expand Up @@ -184,30 +190,75 @@ void ExpressionAnalyser::substituteParametersForExpressions()
for (unsigned int j = 0; j < mExpressions.size(); j++)
{
SubstitutionValues_t* exp = mExpressions[j];
if (exp->type == TYPE_K_MINUS_X_MINUS_Y && exp->z_value.empty())
// if this is the first expression then we need to create a new parameter
// and cannot rely on any other expression
if (j == 0)
{
std::string zName = getUniqueNewParameterName();
exp->z_value = zName;
mNewVarCount++;
ASTNode* z = new ASTNode(AST_NAME);
z->setName(zName.c_str());
exp->z_expression = z->deepCopy();
delete z;
if (exp->type == TYPE_K_MINUS_X_MINUS_Y ||
exp->type == TYPE_K_MINUS_X)
{
// we have a value for k-x-y or k-x
exp->z_expression = z->deepCopy();
delete z;
}
else if (exp->type == TYPE_K_PLUS_V_MINUS_X_MINUS_Y ||
exp->type == TYPE_K_PLUS_V_MINUS_X)
{
// we have a value for k+v-x-y and no value for k-x-y
// we have a value for k+v-x and no value for k-x
ASTNode* replacement = new ASTNode(AST_PLUS);
ASTNode* v = exp->v_expression->deepCopy();
replacement->addChild(z);
replacement->addChild(v);
exp->z_expression = replacement->deepCopy();
delete replacement;
}
else if (exp->type == TYPE_K_MINUS_X_PLUS_W_MINUS_Y)
{
// we have a value for k-x+w-y and no value for k-x-y
ASTNode* replacement = new ASTNode(AST_PLUS);
ASTNode* w = exp->w_expression->deepCopy();
replacement->addChild(z);
replacement->addChild(w);
exp->z_expression = replacement->deepCopy();
delete replacement;
}
}
else if (j > 0 &&
exp->type == TYPE_K_PLUS_V_MINUS_X_MINUS_Y &&
exp->z_expression == NULL)
else
{
// we have a value for k-x-y
ASTNode* replacement = new ASTNode(AST_PLUS);
std::string zName = getUniqueNewParameterName();
exp->z_value = zName;
mNewVarCount++;
ASTNode* z = new ASTNode(AST_NAME);
z->setName(mExpressions[j - 1]->z_value.c_str());
ASTNode* v = exp->v_expression->deepCopy();
replacement->addChild(z);
replacement->addChild(v);
exp->z_expression = replacement->deepCopy();
z->setName(zName.c_str());
if (exp->type == TYPE_K_MINUS_X_MINUS_Y ||
exp->type == TYPE_K_MINUS_X)
{
// we have a different value for k-x-y or k-x
exp->z_expression = z->deepCopy();
delete z;
}

}
//else if (j > 0 &&
// exp->type == TYPE_K_PLUS_V_MINUS_X_MINUS_Y &&
// exp->z_expression == NULL)
//{
// // we have a value for k-x-y
// ASTNode* replacement = new ASTNode(AST_PLUS);
// ASTNode* z = new ASTNode(AST_NAME);
// z->setName(mExpressions[j - 1]->z_value.c_str());
// ASTNode* v = exp->v_expression->deepCopy();
// replacement->addChild(z);
// replacement->addChild(v);
// exp->z_expression = replacement->deepCopy();

//}
}
}

Expand Down Expand Up @@ -731,7 +782,7 @@ ExpressionAnalyser::analyse()

void ExpressionAnalyser::orderExpressions()
{
std::sort(mExpressions.begin(), mExpressions.end(), compareExpressions);
std::sort(mExpressions.begin(), mExpressions.end(), compareExpressions());
}

void
Expand Down
1 change: 0 additions & 1 deletion src/sbml/conversion/ExpressionAnalyser.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ struct SubstitutionValues_t {
unsigned int levelInExpression;
};

bool compareExpressions(SubstitutionValues_t* values1, SubstitutionValues_t* values2);


class LIBSBML_EXTERN ExpressionAnalyser
Expand Down
233 changes: 230 additions & 3 deletions src/sbml/conversion/test/TestExpressionAnalyser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -698,18 +698,239 @@ START_TEST(test_analyse_replace)
delete analyser;
}
END_TEST

START_TEST(test_analyse_same_expression_replace)
{
RateRule* rr = d->getModel()->createRateRule();
rr->setVariable("a");
rr->setMath(SBML_parseFormula("k-x-y"));

RateRule* rr1 = d->getModel()->createRateRule();
rr1->setVariable("b");
rr1->setMath(SBML_parseFormula("k-x-y"));


converter->populateInitialODEinfo();
ExpressionAnalyser* analyser = new ExpressionAnalyser(m, converter->getOdePairs());

fail_unless(analyser->getNumExpressions() == 0);

analyser->detectHiddenSpecies();

fail_unless(analyser->getNumExpressions() == 1);
SubstitutionValues_t* value = analyser->getExpression(0);
fail_unless(value->k_value == "k");
fail_unless(value->x_value == "x");
fail_unless(value->y_value == "y");
fail_unless(value->z_value == "newVar1");
fail_unless(value->type == TYPE_K_MINUS_X_MINUS_Y);
fail_unless(formulas_equal("k - x - y", value->current));
fail_unless(formulas_equal("0", value->dxdt_expression));
fail_unless(formulas_equal("0", value->dydt_expression));
fail_unless(value->v_expression == NULL);
fail_unless(value->w_expression == NULL);
fail_unless(formulas_equal("newVar1", value->z_expression));
fail_unless(value->odeIndex == 0);
fail_unless(util_isNaN(value->k_real_value));

delete analyser;
}
END_TEST

START_TEST(test_analyse_different_expression_replace)
{
// the second expression is the same type but has a different variable
RateRule* rr = d->getModel()->createRateRule();
rr->setVariable("a");
rr->setMath(SBML_parseFormula("k-x-y"));

RateRule* rr1 = d->getModel()->createRateRule();
rr1->setVariable("b");
rr1->setMath(SBML_parseFormula("k-x-a"));


converter->populateInitialODEinfo();
ExpressionAnalyser* analyser = new ExpressionAnalyser(m, converter->getOdePairs());

fail_unless(analyser->getNumExpressions() == 0);

analyser->detectHiddenSpecies();

fail_unless(analyser->getNumExpressions() == 2);
SubstitutionValues_t* value = analyser->getExpression(0);
fail_unless(value->k_value == "k");
fail_unless(value->x_value == "x");
fail_unless(value->y_value == "y");
fail_unless(value->z_value == "newVar1");
fail_unless(value->type == TYPE_K_MINUS_X_MINUS_Y);
fail_unless(formulas_equal("k - x - y", value->current));
fail_unless(formulas_equal("0", value->dxdt_expression));
fail_unless(formulas_equal("0", value->dydt_expression));
fail_unless(value->v_expression == NULL);
fail_unless(value->w_expression == NULL);
fail_unless(formulas_equal("newVar1", value->z_expression));
fail_unless(value->odeIndex == 0);
fail_unless(util_isNaN(value->k_real_value));

SubstitutionValues_t* value1 = analyser->getExpression(1);
fail_unless(value1->k_value == "k");
fail_unless(value1->x_value == "x");
fail_unless(value1->y_value == "a");
fail_unless(value1->z_value == "newVar2");
fail_unless(value1->type == TYPE_K_MINUS_X_MINUS_Y);
fail_unless(formulas_equal("k - x - a", value1->current));
fail_unless(formulas_equal("0", value1->dxdt_expression));
fail_unless(formulas_equal("k - x - y", value1->dydt_expression));
fail_unless(value1->v_expression == NULL);
fail_unless(value1->w_expression == NULL);
fail_unless(formulas_equal("newVar2", value1->z_expression));
fail_unless(value1->odeIndex == 1);
fail_unless(util_isNaN(value1->k_real_value));

delete analyser;
}
END_TEST

START_TEST(test_analyse_1_replace)
{
RateRule* rr = d->getModel()->createRateRule();
rr->setVariable("a");
rr->setMath(SBML_parseFormula("k + v - x - y"));
converter->populateInitialODEinfo();
ExpressionAnalyser* analyser = new ExpressionAnalyser(m, converter->getOdePairs());

fail_unless(analyser->getNumExpressions() == 0);

analyser->detectHiddenSpecies();

fail_unless(analyser->getNumExpressions() == 1);
SubstitutionValues_t* value = analyser->getExpression(0);
fail_unless(value->k_value == "k");
fail_unless(value->x_value == "x");
fail_unless(value->y_value == "y");
fail_unless(value->z_value == "newVar1");
fail_unless(value->type == TYPE_K_PLUS_V_MINUS_X_MINUS_Y);
fail_unless(formulas_equal("k + v - x - y", value->current));
fail_unless(formulas_equal("0", value->dxdt_expression));
fail_unless(formulas_equal("0", value->dydt_expression));
fail_unless(formulas_equal("v", value->v_expression));
fail_unless(value->w_expression == NULL);
fail_unless(formulas_equal("newVar1 + v", value->z_expression));
fail_unless(value->odeIndex == 0);
fail_unless(util_isNaN(value->k_real_value));

delete analyser;
}
END_TEST

START_TEST(test_analyse_2_replace)
{
RateRule* rr = d->getModel()->createRateRule();
rr->setVariable("a");
rr->setMath(SBML_parseFormula("k - x + w - y"));
converter->populateInitialODEinfo();
ExpressionAnalyser* analyser = new ExpressionAnalyser(m, converter->getOdePairs());

fail_unless(analyser->getNumExpressions() == 0);

analyser->detectHiddenSpecies();

fail_unless(analyser->getNumExpressions() == 1);
SubstitutionValues_t* value = analyser->getExpression(0);
fail_unless(value->k_value == "k");
fail_unless(value->x_value == "x");
fail_unless(value->y_value == "y");
fail_unless(value->z_value == "newVar1");
fail_unless(value->type == TYPE_K_MINUS_X_PLUS_W_MINUS_Y);
fail_unless(formulas_equal("w + (k - x) - y", value->current));
fail_unless(formulas_equal("0", value->dxdt_expression));
fail_unless(formulas_equal("0", value->dydt_expression));
fail_unless(formulas_equal("w", value->w_expression));
fail_unless(value->v_expression == NULL);
fail_unless(formulas_equal("newVar1 + w", value->z_expression));
fail_unless(value->odeIndex == 0);
fail_unless(util_isNaN(value->k_real_value));

delete analyser;
}
END_TEST

START_TEST(test_analyse_3_replace)
{
RateRule* rr = d->getModel()->createRateRule();
rr->setVariable("a");
rr->setMath(SBML_parseFormula("k - x"));
converter->populateInitialODEinfo();
ExpressionAnalyser* analyser = new ExpressionAnalyser(m, converter->getOdePairs());

fail_unless(analyser->getNumExpressions() == 0);

analyser->detectHiddenSpecies();

fail_unless(analyser->getNumExpressions() == 1);
SubstitutionValues_t* value = analyser->getExpression(0);
fail_unless(value->k_value == "k");
fail_unless(value->x_value == "x");
fail_unless(value->y_value.empty());
fail_unless(value->z_value == "newVar1");
fail_unless(value->type == TYPE_K_MINUS_X);
fail_unless(formulas_equal("k - x", value->current));
fail_unless(formulas_equal("0", value->dxdt_expression));
fail_unless(value->dydt_expression == NULL);
fail_unless(value->v_expression == NULL);
fail_unless(value->w_expression == NULL);
fail_unless(formulas_equal("newVar1", value->z_expression));
fail_unless(value->odeIndex == 0);
fail_unless(util_isNaN(value->k_real_value));

delete analyser;
}
END_TEST

START_TEST(test_analyse_4_replace)
{
RateRule* rr = d->getModel()->createRateRule();
rr->setVariable("a");
rr->setMath(SBML_parseFormula("k + v - x"));
converter->populateInitialODEinfo();
ExpressionAnalyser* analyser = new ExpressionAnalyser(m, converter->getOdePairs());

fail_unless(analyser->getNumExpressions() == 0);

analyser->detectHiddenSpecies();

fail_unless(analyser->getNumExpressions() == 1);
SubstitutionValues_t* value = analyser->getExpression(0);
fail_unless(value->k_value == "k");
fail_unless(value->x_value == "x");
fail_unless(value->y_value.empty());
fail_unless(value->z_value == "newVar1");
fail_unless(value->type == TYPE_K_PLUS_V_MINUS_X);
fail_unless(formulas_equal("k + v - x", value->current));
fail_unless(formulas_equal("0", value->dxdt_expression));
fail_unless(value->dydt_expression == NULL);
fail_unless(formulas_equal("v", value->v_expression));
fail_unless(value->w_expression == NULL);
fail_unless(formulas_equal("newVar1 + v", value->z_expression));
fail_unless(value->odeIndex == 0);
fail_unless(util_isNaN(value->k_real_value));

delete analyser;
}
END_TEST

Suite *
create_suite_TestExpressionAnalyser (void)
{
bool testing = true;
bool testing = false;
Suite *suite = suite_create("ExpressionAnalyser");
TCase *tcase = tcase_create("ExpressionAnalyser");
tcase_add_checked_fixture(tcase, ExpressionAnalyser_setup,
ExpressionAnalyser_teardown);

if (testing)
{
tcase_add_test(tcase, test_analyse_replace);
tcase_add_test(tcase, test_analyse_4_replace); //k-x-y
}
else
{
Expand All @@ -729,7 +950,12 @@ create_suite_TestExpressionAnalyser (void)
tcase_add_test(tcase, test_order_expressions_3);
tcase_add_test(tcase, test_order_expressions_4);
tcase_add_test(tcase, test_analyse_replace); //k-x-y

tcase_add_test(tcase, test_analyse_same_expression_replace); //k-x-y
tcase_add_test(tcase, test_analyse_different_expression_replace); //k-x-y
tcase_add_test(tcase, test_analyse_1_replace); //k+v-x-y
tcase_add_test(tcase, test_analyse_2_replace); //k-x+w-y
tcase_add_test(tcase, test_analyse_3_replace); //k-x
tcase_add_test(tcase, test_analyse_4_replace); //k+v-x
}
suite_add_tcase(suite, tcase);

Expand All @@ -738,3 +964,4 @@ create_suite_TestExpressionAnalyser (void)
}
END_C_DECLS


Loading

0 comments on commit 17a80dd

Please sign in to comment.