A list for the developers of CellML tools

Text archives Help


[cellml-dev] r2991 - in CellML_DOM_API/trunk: . CCGS/tests


Chronological Thread 
  • From: alan.garny at dpag.ox.ac.uk (Alan Garny)
  • Subject: [cellml-dev] r2991 - in CellML_DOM_API/trunk: . CCGS/tests
  • Date: Thu, 8 Jan 2009 10:09:19 -0000

It is also worth keeping in mind that for CellML2Python at least, a few
things had to be done that are not done in CellML2C. It's true that I didn't
write CellML2Python with the view of testing the CellML API, but I believe
it could help some people who are interested in using the CellML API and
need examples to help them in that process.

Alan

> -----Original Message-----
> From: cellml-tools-developers-bounces at cellml.org [mailto:cellml-tools-
> developers-bounces at cellml.org] On Behalf Of Randall Britten
> Sent: 08 January 2009 04:53
> To: 'A list for the developers of CellML tools'
> Subject: Re: [cellml-dev] r2991 - in CellML_DOM_API/trunk: . CCGS/tests
>
> Something to consider: Having at least one other mal string used for
testing
> CCGS would be valuable, so keeping at least CellML2Python or CellML2Matlab
> would make sense if there was a corresponding test similar to the ones
where
> CellML2C is used.
>
>
>
> -----Original Message-----
> From: cellml-tools-developers-bounces at cellml.org
> [mailto:cellml-tools-developers-bounces at cellml.org] On Behalf Of Andrew
> Miller
> Sent: Thursday, 8 January 2009 4:46 p.m.
> To: cellml-tools-developers at cellml.org
> Subject: Re: [cellml-dev] r2991 - in CellML_DOM_API/trunk: . CCGS/tests
>
> CellML Automated Notifications wrote:
> > Author: aree035
> > Date: 2009-01-08 16:29:51 +1300 (Thu, 08 Jan 2009)
> > New Revision: 2991
> >
> > Added:
> > CellML_DOM_API/trunk/CCGS/tests/CellML2Matlab.cpp
> > Modified:
> > CellML_DOM_API/trunk/
> > CellML_DOM_API/trunk/CCGS/tests/build.mk
> > Log:
> > Added CellML2Matlab program. This does not use simulation metadata like
> the export from PCEnv does.
> >
> I think the CellML2* programs are getting out of hand - CellML2C is
> intended to be part of the tests of the CCGS to ensure that it works
> properly. It is unclear what having CellML2Python and CellML2Matlab
> really achieves in the way of testing - they invoke almost exactly the
> same code paths as CellML2C anyway, just with different strings. There
> may well be demand for a command line user interface for CellML - if so,
> these should really be separate from the API implementation, which is
> intended for programmatic use.
>
> See https://tracker.physiomeproject.org/show_bug.cgi?id=1514#c16, and
> also https://tracker.physiomeproject.org/show_bug.cgi?id=1279 about the
> command line tools.
>
> I will put a note about this on tracker item 1279, and I might also put
> a note in build.mk and CellML2C requesting that people not add any more
> programs like this unless they are useful for testing purposes.
>
> Best wishes,
> Andrew
>
> >
> > Property changes on: CellML_DOM_API/trunk
> > ___________________________________________________________________
> > Name: svn:ignore
> > - Makefile.in
> > Makefile
> > aclocal.m4
> > cda_config.h
> > config.log
> > config.status
> > configure.scan
> > configure
> > autom4te.cache
> > stamp-h1
> > libtool
> > .deps
> > .libs
> > cellml_corba_server
> > CellML2C
> > CellML2Python
> > CCGSService
> > CISService
> > RunCellML
> > ValidateCellML
> > a.exe.manifest
> > vc80.pdb
> >
> > + Makefile.in
> > Makefile
> > aclocal.m4
> > cda_config.h
> > config.log
> > config.status
> > configure.scan
> > configure
> > autom4te.cache
> > stamp-h1
> > libtool
> > .deps
> > .libs
> > cellml_corba_server
> > CellML2C
> > CellML2Python
> > CellML2Matlab
> > CCGSService
> > CISService
> > RunCellML
> > ValidateCellML
> > a.exe.manifest
> > vc80.pdb
> >
> >
> > Added: CellML_DOM_API/trunk/CCGS/tests/CellML2Matlab.cpp
> > ===================================================================
> > --- CellML_DOM_API/trunk/CCGS/tests/CellML2Matlab.cpp
> (rev 0)
> > +++ CellML_DOM_API/trunk/CCGS/tests/CellML2Matlab.cpp 2009-01-08
> 03:29:51
> UTC (rev 2991)
> > @@ -0,0 +1,801 @@
> > +#include "cda_config.h"
> > +#ifdef HAVE_INTTYPES_H
> > +#include <inttypes.h>
> > +#endif
> > +#include <exception>
> > +#include "cda_compiler_support.h"
> > +#include "IfaceCellML_APISPEC.hxx"
> > +#include "IfaceCCGS.hxx"
> > +#include "IfaceMaLaES.hxx"
> > +#include "IfaceAnnoTools.hxx"
> > +#include "CCGSBootstrap.hpp"
> > +#include "MaLaESBootstrap.hpp"
> > +#include "CellMLBootstrap.hpp"
> > +#include "AnnoToolsBootstrap.hpp"
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <wchar.h>
> > +#include <vector>
> > +#include <algorithm>
> > +#include <string>
> > +#include "Utilities.hxx"
> > +
> > +#ifdef _WIN32
> > +#define swprintf _snwprintf
> > +#endif
> > +
> > +wchar_t*
> > +TypeToString(iface::cellml_services::VariableEvaluationType vet)
> > +{
> > + switch (vet)
> > + {
> > + case iface::cellml_services::VARIABLE_OF_INTEGRATION:
> > + return L"variable of integration";
> > + case iface::cellml_services::CONSTANT:
> > + return L"constant";
> > + case iface::cellml_services::STATE_VARIABLE:
> > + return L"state variable";
> > + case iface::cellml_services::ALGEBRAIC:
> > + return L"algebraic variable";
> > + case iface::cellml_services::FLOATING:
> > + return L"uncomputed";
> > + }
> > +
> > + return L"invalid type";
> > +}
> > +
> > +void
> > +WriteCode(iface::cellml_services::CodeInformation* cci)
> > +{
> > + // Scoped locale change.
> > + CNumericLocale locobj;
> > +
> > + iface::cellml_services::ModelConstraintLevel mcl =
> > + cci->constraintLevel();
> > + if (mcl == iface::cellml_services::UNDERCONSTRAINED)
> > + {
> > + printf("Model is underconstrained.\n"
> > + "List of undefined targets follows...\n");
> > + iface::cellml_services::ComputationTargetIterator* cti =
> cci->iterateTargets();
> > + iface::cellml_services::ComputationTarget* ct;
> > + std::vector<std::wstring> messages;
> > + while (true)
> > + {
> > + ct = cti->nextComputationTarget();
> > + if (ct == NULL)
> > + break;
> > + if (ct->type() != iface::cellml_services::FLOATING)
> > + {
> > + ct->release_ref();
> > + continue;
> > + }
> > + iface::cellml_api::CellMLVariable* v = ct->variable();
> > + wchar_t* n = v->name();
> > + wchar_t* c = v->componentName();
> > + std::wstring str = L" ";
> > + uint32_t deg = ct->degree();
> > + if (deg != 0)
> > + {
> > + str += L"d^";
> > + wchar_t buf[20];
> > + swprintf(buf, 20, L"%u", deg);
> > + str += buf;
> > + str += L"/dt^";
> > + str += buf;
> > + str += L" ";
> > + }
> > + str += n;
> > + str += L" (in ";
> > + str += c;
> > + str += L")\n";
> > + free(n);
> > + free(c);
> > + messages.push_back(str);
> > + v->release_ref();
> > + ct->release_ref();
> > + }
> > + cti->release_ref();
> > + // Sort the messages...
> > + std::sort(messages.begin(), messages.end());
> > + std::vector<std::wstring>::iterator msgi;
> > + for (msgi = messages.begin(); msgi != messages.end(); msgi++)
> > + printf("%S", (*msgi).c_str());
> > + return;
> > + }
> > + else if (mcl == iface::cellml_services::OVERCONSTRAINED)
> > + {
> > + printf("Model is overconstrained.\n"
> > + "List variables defined at time of error follows...\n");
> > + iface::cellml_services::ComputationTargetIterator* cti =
> cci->iterateTargets();
> > + iface::cellml_services::ComputationTarget* ct;
> > + std::vector<std::wstring> messages;
> > + while (true)
> > + {
> > + ct = cti->nextComputationTarget();
> > + if (ct == NULL)
> > + break;
> > + if (ct->type() == iface::cellml_services::FLOATING)
> > + {
> > + ct->release_ref();
> > + continue;
> > + }
> > + iface::cellml_api::CellMLVariable* v = ct->variable();
> > + wchar_t* n = v->name();
> > + std::wstring str = L" ";
> > + uint32_t deg = ct->degree();
> > + if (deg != 0)
> > + {
> > + str += L"d^";
> > + wchar_t buf[20];
> > + swprintf(buf, 20, L"%u", deg);
> > + str += buf;
> > + str += L"/dt^";
> > + str += buf;
> > + str += L" ";
> > + }
> > + str += n;
> > + free(n);
> > + str += L"\n";
> > + messages.push_back(str);
> > + v->release_ref();
> > + ct->release_ref();
> > + }
> > + cti->release_ref();
> > +
> > + // Sort the messages...
> > + std::sort(messages.begin(), messages.end());
> > + std::vector<std::wstring>::iterator msgi;
> > + for (msgi = messages.begin(); msgi != messages.end(); msgi++)
> > + printf("%S", (*msgi).c_str());
> > +
> > + // Get flagged equations...
> > + iface::mathml_dom::MathMLNodeList* mnl = cci->flaggedEquations();
> > + printf("Extraneous equation was:\n");
> > + iface::dom::Node* n = mnl->item(0);
> > + mnl->release_ref();
> > + iface::dom::Element* el =
> > +
>
reinterpret_cast<iface::dom::Element*>(n->query_interface("dom::Element"));
> > + n->release_ref();
> > +
> > + wchar_t* cmeta =
> el->getAttributeNS(L"http://www.cellml.org/metadata/1.0#";,
> > + L"id");
> > + if (!wcscmp(cmeta, L""))
> > + printf(" <equation with no cmeta ID>\n");
> > + else
> > + printf(" %S\n", cmeta);
> > + free(cmeta);
> > +
> > + n = el->parentNode();
> > + el->release_ref();
> > +
> > + el = reinterpret_cast<iface::dom::Element*>
> > + (n->query_interface("dom::Element"));
> > + n->release_ref();
> > +
> > + cmeta = el->getAttributeNS(L"http://www.cellml.org/metadata/1.0#";,
> L"id");
> > + if (!wcscmp(cmeta, L""))
> > + printf(" in <math with no cmeta ID>\n");
> > + else
> > + printf(" in math with cmeta:id %S\n", cmeta);
> > + free(cmeta);
> > + el->release_ref();
> > +
> > + return;
> > + }
> > + else if (mcl == iface::cellml_services::UNSUITABLY_CONSTRAINED)
> > + {
> > + printf("Model is unsuitably constrained (i.e. would need
> capabilities"
> > + "beyond those of the CCGS to solve).\n"
> > + "The status of variables at time of error follows...\n");
> > + iface::cellml_services::ComputationTargetIterator* cti =
> cci->iterateTargets();
> > + iface::cellml_services::ComputationTarget* ct;
> > + std::vector<std::wstring> messages;
> > + while (true)
> > + {
> > + ct = cti->nextComputationTarget();
> > + if (ct == NULL)
> > + break;
> > + std::wstring str = L" ";
> > + if (ct->type() == iface::cellml_services::FLOATING)
> > + str += L" Undefined: ";
> > + else
> > + str += L" Defined: ";
> > +
> > + uint32_t deg = ct->degree();
> > + if (deg != 0)
> > + {
> > + str += L"d^";
> > + wchar_t buf[20];
> > + swprintf(buf, 20, L"%u", deg);
> > + str += buf;
> > + str += L"/dt^";
> > + str += buf;
> > + str += L" ";
> > + }
> > + iface::cellml_api::CellMLVariable* v = ct->variable();
> > + wchar_t* n = v->name();
> > + str += n;
> > + free(n);
> > + str += L"\n";
> > + messages.push_back(str);
> > + v->release_ref();
> > + ct->release_ref();
> > + }
> > + cti->release_ref();
> > +
> > + // Sort the messages...
> > + std::sort(messages.begin(), messages.end());
> > + std::vector<std::wstring>::iterator msgi;
> > + for (msgi = messages.begin(); msgi != messages.end(); msgi++)
> > + printf("%S", (*msgi).c_str());
> > +
> > + return;
> > + }
> > +
> > + printf("%% Model is correctly constrained.\n");
> > + iface::mathml_dom::MathMLNodeList* mnl = cci->flaggedEquations();
> > + uint32_t i, l = mnl->length();
> > + if (l == 0)
> > + printf("%% No equations needed Newton-Raphson evaluation.\n");
> > + else
> > + printf("%% The following equations needed Newton-Raphson
> evaluation:\n");
> > +
> > + std::vector<std::wstring> messages;
> > + for (i = 0; i < l; i++)
> > + {
> > + iface::dom::Node* n = mnl->item(i);
> > + iface::dom::Element* el =
> > +
>
reinterpret_cast<iface::dom::Element*>(n->query_interface("dom::Element"));
> > + n->release_ref();
> > +
> > + wchar_t* cmeta =
> el->getAttributeNS(L"http://www.cellml.org/metadata/1.0#";,
> > + L"id");
> > + std::wstring str;
> > + if (!wcscmp(cmeta, L""))
> > + str += L"% <equation with no cmeta ID>\n";
> > + else
> > + {
> > + str += L"% ";
> > + str += cmeta;
> > + str += L"\n";
> > + }
> > + free(cmeta);
> > +
> > + n = el->parentNode();
> > + el->release_ref();
> > +
> > + el = reinterpret_cast<iface::dom::Element*>
> > + (n->query_interface("dom::Element"));
> > + n->release_ref();
> > +
> > + cmeta = el->getAttributeNS(L"http://www.cellml.org/metadata/1.0#";,
> L"id");
> > + if (!wcscmp(cmeta, L""))
> > + str += L"% in <math with no cmeta ID>\n";
> > + else
> > + {
> > + str += L"% in math with cmeta:id ";
> > + str += cmeta;
> > + str += L"\n";
> > + }
> > + free(cmeta);
> > + el->release_ref();
> > +
> > + messages.push_back(str);
> > + }
> > + mnl->release_ref();
> > +
> > + // Sort the messages...
> > + std::sort(messages.begin(), messages.end());
> > + std::vector<std::wstring>::iterator msgi;
> > + for (msgi = messages.begin(); msgi != messages.end(); msgi++)
> > + printf("%S", (*msgi).c_str());
> > +
> > + printf("%%\r\n%% There are a total of %u entries in the algebraic
> variable array.\n", cci->algebraicIndexCount());
> > + printf("%% There are a total of %u entries in each of the rates &
state
> variable arrays.\n", cci->rateIndexCount());
> > + printf("%% There are a total of %u entries in the constant variable
> array.\n%%\r\n", cci->constantIndexCount());
> > +
> > + messages.clear();
> > + iface::cellml_services::ComputationTargetIterator* cti =
> cci->iterateTargets();
> > + while (true)
> > + {
> > + iface::cellml_services::ComputationTarget* ct =
> cti->nextComputationTarget();
> > + if (ct == NULL)
> > + break;
> > + iface::cellml_api::CellMLVariable* v = ct->variable();
> > + iface::cellml_api::CellMLElement* el = v->parentElement();
> > + iface::cellml_api::CellMLComponent* c =
> > + reinterpret_cast<iface::cellml_api::CellMLComponent*>
> > + (el->query_interface("cellml_api::CellMLComponent"));
> > + el->release_ref();
> > +
> > + std::wstring str;
> > + wchar_t* vn = v->name(), * cn = c->name();
> > +
> > + str += L" LEGEND_";
> > + wchar_t * vsn;
> > + vsn = ct->name();
> > + str += vsn;
> > + free(vsn);
> > +
> > + str += L" = strpad('";
> > + uint32_t deg = ct->degree();
> > + if (deg != 0)
> > + {
> > + str += L"d^";
> > + wchar_t buf[20];
> > + swprintf(buf, 20, L"%u", deg);
> > + str += buf;
> > + str += L"/dt^";
> > + str += buf;
> > + str += L" ";
> > + }
> > + str += vn;
> > + str += L" in component ";
> > + str += cn;
> > + str += L"');\n";
> > + free(vn);
> > + free(cn);
> > +
> > + c->release_ref();
> > + v->release_ref();
> > + ct->release_ref();
> > +
> > + messages.push_back(str);
> > + }
> > + cti->release_ref();
> > +
> > + // Now start the code...
> > +
> > + printf("\r\n"
> > + "function [VOI, STATES, ALGEBRAIC, CONSTANTS] =
> solveModel()\r\n"
> > + " %% Initialise constants and state variables\r\n"
> > + " [INIT_STATES, CONSTANTS] = initConsts;\r\n\r\n"
> > + " %% Set timespan to solve over\r\n"
> > + " tspan = [0,10];\r\n"
> > + " %% Set numerical accuracy options for ODE solver\r\n"
> > + " options = odeset('RelTol', 1E-6, 'AbsTol', 1E-6,
'MaxStep',
> 0.1);\r\n\r\n"
> > + " %% Solve model with ODE solver\r\n"
> > + " [VOI, STATES] = ode15s(@(VOI, STATES)computeRates(VOI,
> STATES, CONSTANTS), tspan, INIT_STATES, options);\r\n\r\n"
> > + " %% Compute algebraic variables\r\n"
> > + " ALGEBRAIC = computeAlgebraic(CONSTANTS, STATES,
> VOI);\r\n\r\n"
> > + " %% Plot state variables against variable of
> integration\r\n"
> > + " [LEGEND_STATES, LEGEND_ALGEBRAIC, LEGEND_VOI,
> LEGEND_CONSTANTS] = createLegends();\r\n"
> > + " figure();\r\n"
> > + " plot(VOI, STATES);\r\n"
> > + " xlabel(LEGEND_VOI);\r\n"
> > + " l = legend(LEGEND_STATES);\r\n"
> > + " set(l,'Interpreter','none');\r\n"
> > + "end\r\n\r\n");
> > +
> > + // Sort and print the list of variables
> > + std::sort(messages.begin(), messages.end());
> > + printf("function [LEGEND_STATES, LEGEND_ALGEBRAIC, LEGEND_VOI,
> LEGEND_CONSTANTS] = createLegends()\r\n"
> > + " LEGEND_STATES = ''; LEGEND_ALGEBRAIC = ''; LEGEND_VOI = '';
> LEGEND_CONSTANTS = '';\r\n");
> > + for (msgi = messages.begin(); msgi != messages.end(); msgi++)
> > + printf("%S", (*msgi).c_str());
> > + printf(" LEGEND_STATES = LEGEND_STATES';\r\n"
> > + " LEGEND_ALGEBRAIC = LEGEND_ALGEBRAIC';\r\n"
> > + " LEGEND_RATES = LEGEND_RATES';\r\n"
> > + " LEGEND_CONSTANTS = LEGEND_CONSTANTS';\r\n"
> > + "end\r\n\r\n");
> > +
> > + wchar_t* frag = cci->initConstsString();
> > + printf("function [STATES, CONSTANTS] = initConsts()\r\n CONSTANTS
=
> []; STATES = [];\r\n");
> > + printf("%S", frag);
> > + printf(" if (isempty(STATES)), warning('Initial values for states
> not set');, end\r\nend\r\n\r\n");
> > + free(frag);
> > +
> > + frag = cci->ratesString();
> > + printf("function RATES = computeRates(VOI, STATES, CONSTANTS)\r\n"
> > + " STATES = STATES'; RATES = []; ALGEBRAIC = [0];\r\n");
> > + printf("%S", frag);
> > + printf(" RATES = RATES';\r\nend\r\n\r\n");
> > + free(frag);
> > +
> > + printf("%% Calculate algebraic variables\r\n"
> > + "function ALGEBRAIC = computeAlgebraic(CONSTANTS, STATES,
> VOI)\r\n"
> > + " ALGEBRAIC = zeros(length(VOI),1);\r\n");
> > +
> > + // Copy algebraic variable calculations from rate calculations
> > + // Use lines beginning with 'A'
> > + frag = cci->ratesString();
> > + i = 0;
> > + bool algebraic = false, newline = true;
> > +
> > + while(frag[i] != '\0') {
> > + if(frag[i] == ' ' || frag[i] == '\t') {
> > + i++;
> > + continue;
> > + }
> > + if(newline && frag[i] == 'A') {
> > + algebraic = true;
> > + newline = false;
> > + printf(" ");
> > + }
> > + else if (newline) {
> > + newline = false;
> > + }
> > + if(algebraic) {
> > + printf("%C", frag[i]);
> > + }
> > + if(frag[i] == '\n') {
> > + newline = true;
> > + algebraic = false;
> > + }
> > + i++;
> > + }
> > + free(frag);
> > +
> > + frag = cci->variablesString();
> > + printf("%S",frag);
> > + free(frag);
> > + printf("end\r\n\r\n"
> > + "%% Compute result of a piecewise function\r\n"
> > + "function x = piecewise(cases, default)\r\n"
> > + " set = [0];\r\n"
> > + " for i = 1:2:length(cases)\r\n"
> > + " if (length(cases{i+1}) == 1)\r\n"
> > + " x(cases{i} & ~set,:) = cases{i+1};\r\n"
> > + " else\r\n"
> > + " x(cases{i} & ~set,:) = cases{i+1}(cases{i} &
> ~set);\r\n"
> > + " end\r\n"
> > + " set = set | cases{i};\r\n"
> > + " if(set), break, end\r\n"
> > + " end\r\n"
> > + " if (length(default) == 1)\r\n"
> > + " x(~set,:) = default;\r\n"
> > + " else\r\n"
> > + " x(~set,:) = default(~set);\r\n"
> > + " end\r\n"
> > + "end\r\n"
> > + "%% Pad out or shorten strings to a set length\r\n"
> > + "function strout = strpad(strin)\r\n"
> > + " req_length = 50;\r\n"
> > + " insize = size(strin,2);\r\n"
> > + " if insize > req_length\r\n"
> > + " strout = strin(1:req_length);\r\n"
> > + " else\r\n"
> > + " strout = [strin, blanks(req_length - insize)];\r\n"
> > + " end\r\n"
> > + "end\r\n"
> > + "%% Compute a logarithm to any base\r\n"
> > + "function x = arbitrary_log(a, base)\r\n"
> > + " x = log(a) ./ log(base);\r\n"
> > + "end\r\n"
> > + "%% Least common multiple\r\n"
> > + "function m = lcm_multi(x)\r\n"
> > + " m = x(1);\r\n"
> > + " for (i = 1:size(x,2))\r\n"
> > + " if(x(i) ~= 0), m = m./gcd(m,x(i)).*x(i);, end\r\n"
> > + " end\r\n"
> > + "end\r\n"
> > + "%% Greatest common divisor\r\n"
> > + "function d = gcd_multi(x)\r\n"
> > + " d = 0;\r\n"
> > + " for (i = 1:size(x,2)), d = gcd(d, x(:,i));, end\r\n"
> > + "end\r\n\r\n");
> > +
> > + frag = cci->functionsString();
> > + printf("%S\n", frag);
> > + free(frag);
> > +}
> > +
> > +void
> > +doNameAnnotations(iface::cellml_api::Model* aModel,
> > + iface::cellml_services::CodeGenerator* aCG)
> > +{
> > + // Make an annotation set...
> > + iface::cellml_services::AnnotationToolService* ats
> > + (CreateAnnotationToolService());
> > + iface::cellml_services::AnnotationSet*
as(ats->createAnnotationSet());
> > + ats->release_ref();
> > +
> > + aCG->useAnnoSet(as);
> > +
> > + // Now we go through all variables in the model and set their
> annotations...
> > + iface::cellml_api::CellMLComponentSet* ccs = aModel->allComponents();
> > +
> > + iface::cellml_api::CellMLComponentIterator* cci =
> ccs->iterateComponents();
> > + ccs->release_ref();
> > +
> > + iface::cellml_api::CellMLComponent* comp;
> > + while ((comp = cci->nextComponent()) != NULL)
> > + {
> > + iface::cellml_api::CellMLVariableSet* vs(comp->variables());
> > + wchar_t* compname = comp->name();
> > + comp->release_ref();
> > + iface::cellml_api::CellMLVariableIterator*
> vi(vs->iterateVariables());
> > + vs->release_ref();
> > +
> > + iface::cellml_api::CellMLVariable* v;
> > + while ((v = vi->nextVariable()) != NULL)
> > + {
> > + wchar_t* name = v->name();
> > + std::wstring varn = compname;
> > + varn += L"_";
> > + varn += name;
> > + free(name);
> > + std::wstring raten = L"rate_";
> > + raten += varn;
> > + as->setStringAnnotation(v, L"expression", varn.c_str());
> > + as->setStringAnnotation(v, L"expression_d1", raten.c_str());
> > + v->release_ref();
> > + }
> > +
> > + vi->release_ref();
> > +
> > + free(compname);
> > + }
> > +
> > + cci->release_ref();
> > +
> > + as->release_ref();
> > +}
> > +
> > +int
> > +main(int argc, char** argv)
> > +{
> > + // Get the URL from which to load the model...
> > + if (argc < 2)
> > + {
> > + printf("Usage: CellML2Matlab modelURL\n");
> > + return -1;
> > + }
> > +
> > + uint32_t usenames = 0;
> > +
> > + if (argc > 2)
> > + {
> > + if (!strcmp(argv[2], "usenames"))
> > + usenames = 1;
> > + }
> > +
> > + wchar_t* URL;
> > + size_t l = strlen(argv[1]);
> > + URL = new wchar_t[l + 1];
> > + memset(URL, 0, (l + 1) * sizeof(wchar_t));
> > + const char* mbrurl = argv[1];
> > + mbsrtowcs(URL, &mbrurl, l, NULL);
> > +
> > + iface::cellml_api::CellMLBootstrap* cb =
> > + CreateCellMLBootstrap();
> > +
> > + iface::cellml_api::ModelLoader* ml =
> > + cb->modelLoader();
> > + cb->release_ref();
> > +
> > + iface::cellml_api::Model* mod;
> > + try
> > + {
> > + mod = ml->loadFromURL(URL);
> > + }
> > + catch (...)
> > + {
> > + printf("Error loading model URL.\n");
> > + // Well, a leak on exit wouldn't be so bad, but someone might reuse
> this
> > + // code, so...
> > + delete [] URL;
> > + ml->release_ref();
> > + return -1;
> > + }
> > +
> > + ml->release_ref();
> > + delete [] URL;
> > +
> > + iface::cellml_services::CodeGeneratorBootstrap* cgb =
> > + CreateCodeGeneratorBootstrap();
> > + iface::cellml_services::CodeGenerator* cg =
> > + cgb->createCodeGenerator();
> > + cgb->release_ref();
> > +
> > + // The code generator is designed to generate C code by default, so
> > + // we need to customise it to generate Matlab code instead
> > +
> > + cg->constantPattern(L"CONSTANTS(:,%)");
> > + cg->stateVariableNamePattern(L"STATES(:,%)");
> > + cg->algebraicVariableNamePattern(L"ALGEBRAIC(:,%)");
> > + cg->rateNamePattern(L"RATES(:,%)");
> > + cg->voiPattern(L"VOI");
> > + cg->assignPattern(L" <LHS> = <RHS>;\r\n");
> > + cg->arrayOffset(1);
> > + cg->solvePattern(L"ALGEBRAIC = rootfind_<ID>(VOI, CONSTANTS, STATES,
> ALGEBRAIC);\r\n"
> > + L"<SUP>"
> > + L"% Functions required for solving differential algebraic
equation\r\n"
>
> > + L"function ALGEBRAIC = rootfind_<ID>(VOI, CONSTANTS, STATES,
> ALGEBRAIC_IN)\r\n"
> > + L" ALGEBRAIC = ALGEBRAIC_IN;\r\n"
> > + L" global initialGuess;\r\n"
> > + L" if (length(initialGuess) ~= 1), initialGuess = getInitialGuess"
> > + L" options = optimset('Display', 'off', 'TolX', 1E-6);\r\n"
> > + L" if length(VOI) == 1\r\n"
> > + L" residualfn =
> @(algebraicCandidate)residualSN_<ID>(algebraicCandidate, ALGEBRAIC, VOI,
> CONSTANTS, STATES);\r\n"
> > + L" <VAR> = fsolve(residualfn, initialGuess, options);\r\n"
> > + L" initialGuess = <VAR>;\r\n"
> > + L" else\r\n"
> > + L" SET_<VAR> = logical(1);\r\n"
> > + L" for i=1:length(VOI)\r\n"
> > + L" residualfn =
> @(algebraicCandidate)residualSN_<ID>(algebraicCandidate, ALGEBRAIC(i,:),
> VOI(i), CONSTANTS, STATES(i,:));\r\n"
> > + L" TEMP_<VAR> = fsolve(residualfn, initialGuess,
> options);\r\n"
> > + L" ALGEBRAIC(i,SET_ALGEBRAIC) =
> TEMP_ALGEBRAIC(SET_ALGEBRAIC);\r\n"
> > + L" initialGuess = TEMP_<VAR>;\r\n"
> > + L" end\r\n"
> > + L" end\r\n"
> > + L"end\r\n"
> > + L"function resid = residualSN_<ID>(algebraicCandidate, ALGEBRAIC,
VOI,
> CONSTANTS, STATES)\r\n"
> > + L" <VAR> = algebraicCandidate;\r\n"
> > + L" resid = fixnans((<LHS>) - (<RHS>));\r\n"
> > + L"end\r\n"
> > + L"function algebraicGuess = getInitialGuess(count)\r\n"
> > + L" algebraicGuess = ones(count,1) * 0.1;\r\n"
> > + L"end\r\n"
> > + L"function xfixed = fixnans(x)\r\n"
> > + L" xfixed = x;\r\n"
> > + L" xfixed(isnan(x)) = 1.0;\r\n"
> > + L" xfixed(isinf(x)) = 1E1000;\r\n"
> > + L"end\r\n");
> > + cg->solveNLSystemPattern(L"ALGEBRAIC = rootfind_<ID>(VOI, CONSTANTS,
> STATES, ALGEBRAIC);\r\n"
> > + L"<SUP>"
> > + L"% Functions required for solving differential algebraic
equation\r\n"
>
> > + L"function ALGEBRAIC = rootfind_<ID>(VOI, CONSTANTS, STATES,
> ALGEBRAIC_IN)\r\n"
> > + L" ALGEBRAIC = ALGEBRAIC_IN;\r\n"
> > + L" global initialGuess;\r\n"
> > + L" if (length(initialGuess) ~= <COUNT>), initialGuess =
> getInitialGuess(<COUNT>);, end\r\n"
> > + L" options = optimset('Display', 'off', 'TolX', 1E-6);\r\n"
> > + L" if length(VOI) == 1\r\n"
> > + L" residualfn =
> @(algebraicCandidate)residualSN_<ID>(algebraicCandidate, ALGEBRAIC, VOI,
> CONSTANTS, STATES);\r\n"
> > + L" soln = fsolve(residualfn, initialGuess, options);\r\n"
> > + L" initialGuess = soln;\r\n"
> > + L" <EQUATIONS><VAR> = soln(<INDEX>);<JOIN>\r\n"
> > + L" </EQUATIONS>\r\n"
> > + L" else\r\n"
> > + L" <EQUATIONS>SET_<VAR> = logical(1);<JOIN>\r\n"
> > + L" </EQUATIONS>\r\n"
> > + L" for i=1:length(VOI)\r\n"
> > + L" residualfn =
> @(algebraicCandidate)residualSN_<ID>(algebraicCandidate, ALGEBRAIC(i,:),
> VOI(i), CONSTANTS, STATES(i,:));\r\n"
> > + L" soln = fsolve(residualfn, initialGuess, options);\r\n"
> > + L" initialGuess = soln;\r\n"
> > + L" <EQUATIONS>TEMP_<VAR> = soln(<INDEX>);<JOIN>\r\n"
> > + L" </EQUATIONS>\r\n"
> > + L" ALGEBRAIC(i,SET_ALGEBRAIC) =
> TEMP_ALGEBRAIC(SET_ALGEBRAIC);\r\n"
> > + L" end\r\n"
> > + L" end\r\n"
> > + L"end\r\n"
> > + L"function resid = residualSN_<ID>(algebraicCandidate, ALGEBRAIC,
VOI,
> CONSTANTS, STATES)\r\n"
> > + L" <EQUATIONS><VAR> = algebraicCandidate(<INDEX>);<JOIN>\r\n"
> > + L" </EQUATIONS>\r\n"
> > + L" <EQUATIONS>resid(<INDEX>) = fixnans((<LHS>) -
> (<RHS>));<JOIN>\r\n"
> > + L" </EQUATIONS>\r\n"
> > + L"end\r\n"
> > + L"function algebraicGuess = getInitialGuess(count)\r\n"
> > + L" algebraicGuess = ones(count,1) * 0.1;\r\n"
> > + L"end\r\n"
> > + L"function xfixed = fixnans(x)\r\n"
> > + L" xfixed = x;\r\n"
> > + L" xfixed(isnan(x)) = 1.0;\r\n"
> > + L" xfixed(isinf(x)) = 1E1000;\r\n"
> > + L"end\r\n");
> > +
> > + iface::cellml_services::MaLaESBootstrap* mb =
CreateMaLaESBootstrap();
> > +
> > + iface::cellml_services::MaLaESTransform* mt =
> > + mb->compileTransformer
> > + (
> > + L"opengroup: (\r\n"
> > + L"closegroup: )\r\n"
> > + L"abs: #prec[H]abs(#expr1)\r\n"
> > + L"and: #prec[20]#exprs[&]\r\n"
> > + L"arccos: #prec[H]acos(#expr1)\r\n"
> > + L"arccosh: #prec[H]acosh(#expr1)\r\n"
> > + L"arccot: #prec[H]acot(#expr1)\r\n"
> > + L"arccoth: #prec[H]acoth(#expr1)\r\n"
> > + L"arccsc: #prec[H]acsc(#expr1)\r\n"
> > + L"arccsch: #prec[H]acsch(#expr1)\r\n"
> > + L"arcsec: #prec[H]asec(#expr1)\r\n"
> > + L"arcsech: #prec[H]asech(#expr1)\r\n"
> > + L"arcsin: #prec[H]asin(#expr1)\r\n"
> > + L"arcsinh: #prec[H]asinh(#expr1)\r\n"
> > + L"arctan: #prec[H]atan(#expr1)\r\n"
> > + L"arctanh: #prec[H]atanh(#expr1)\r\n"
> > + L"ceiling: #prec[H]ceil(#expr1)\r\n"
> > + L"cos: #prec[H]cos(#expr1)\r\n"
> > + L"cosh: #prec[H]cosh(#expr1)\r\n"
> > + L"cot: #prec[H]cot(#expr1)\r\n"
> > + L"coth: #prec[H]coth(#expr1)\r\n"
> > + L"csc: #prec[H]csc(#expr1)\r\n"
> > + L"csch: #prec[H]csch(#expr1)\r\n"
> > + L"diff: #lookupDiffVariable\r\n"
> > + L"divide: #prec[900]#expr1./#expr2\r\n"
> > + L"eq: #prec[30]#exprs[==]\r\n"
> > + L"exp: #prec[H]exp(#expr1)\r\n"
> > + L"factorial: #prec[H]factorial(#expr1)\r\n"
> > + L"factorof: #prec[30(900)]mod(#expr1, #expr2) == 0\r\n"
> > + L"floor: #prec[H]floor(#expr1)\r\n"
> > + L"gcd: #prec[H]gcd_multi([#exprs[, ]])\r\n"
> > + L"geq: #prec[30]#exprs[>=]\r\n"
> > + L"gt: #prec[30]#exprs[>]\r\n"
> > + L"implies: #prec[10(950)] ~#expr1 | #expr2\r\n"
> > + L"int: #prec[H]defint(func#unique1, BOUND, CONSTANTS, RATES,
VARIABLES,
> "
> > + L"#bvarIndex)#supplement double func#unique1(double* BOUND, "
> > + L"double* CONSTANTS, double* RATES, double* VARIABLES) { return
#expr1;
> }\r\n"
> > + L"lcm: #prec[H]lcm_multi([#exprs[, ]])\r\n"
> > + L"leq: #prec[30]#exprs[<=]\r\n"
> > + L"ln: #prec[H]log(#expr1)\r\n"
> > + L"log: #prec[H]arbitrary_log(#expr1, #logbase)\r\n"
> > + L"lt: #prec[30]#exprs[<]\r\n"
> > + L"max: #prec[H]max([#exprs[, ]],[],2)\r\n"
> > + L"min: #prec[H]min([#exprs[, ]],[],2)\r\n"
> > + L"minus: #prec[500]#expr1 - #expr2\r\n"
> > + L"neq: #prec[30]#expr1 ~= #expr2\r\n"
> > + L"not: #prec[950]~#expr1\r\n"
> > + L"or: #prec[10]#exprs[|]\r\n"
> > + L"plus: #prec[500]#exprs[+]\r\n"
> > + L"power: #prec[H]#expr1 .^ #expr2\r\n"
> > + L"quotient: #prec[900(0)] floor(#expr1 ./ #expr2)\r\n"
> > + L"rem: #prec[900(0)] rem(#expr1, #expr2)\r\n"
> > + L"root: #prec[1000(900)] #expr1 .^ (1.0 / #degree)\r\n"
> > + L"sec: #prec[H]sec(#expr1)\r\n"
> > + L"sech: #prec[H]sech(#expr1)\r\n"
> > + L"sin: #prec[H] sin(#expr1)\r\n"
> > + L"sinh: #prec[H] sinh(#expr1)\r\n"
> > + L"tan: #prec[H] tan(#expr1)\r\n"
> > + L"tanh: #prec[H] tanh(#expr1)\r\n"
> > + L"times: #prec[900] #exprs[.*]\r\n"
> > + L"unary_minus: #prec[950] - #expr1\r\n"
> > + L"units_conversion: #prec[500(900)]#expr1.*#expr2 + #expr3\r\n"
> > + L"units_conversion_factor: #prec[900]#expr1.*#expr2\r\n"
> > + L"units_conversion_offset: #prec[500]#expr1+#expr2\r\n"
> > + L"xor: #prec[25(30)]xor(#expr1 , #expr2)\r\n"
> > + L"piecewise_first_case: #prec[5]piecewise({#expr1, #expr2 \r\n"
> > + L"piecewise_extra_case: #prec[5], #expr1, #expr2 \r\n"
> > + L"piecewise_otherwise: #prec[5]}, #expr1)\r\n"
> > + L"piecewise_no_otherwise: #prec[5]}, NaN)\r\n"
> > + L"pi: #prec[999] pi\r\n"
> > + L"eulergamma: #prec[999]0.577215664901533\r\n"
> > + L"infinity: #prec[900] Inf\r\n"
> > + );
> > +
> > + cg->transform(mt);
> > +
> > + mt->release_ref();
> > + mb->release_ref();
> > +
> > + if (usenames)
> > + doNameAnnotations(mod, cg);
> > +
> > + iface::cellml_services::CodeInformation* cci = NULL;
> > + try
> > + {
> > + cci = cg->generateCode(mod);
> > + }
> > + catch (iface::cellml_api::CellMLException& ce)
> > + {
> > + printf("Caught a CellMLException while generating code.\n");
> > + cg->release_ref();
> > + mod->release_ref();
> > + return -1;
> > + }
> > + catch (...)
> > + {
> > + printf("Unexpected exception calling generateCode!\n");
> > + // this is a leak, but it should also never happen :)
> > + return -1;
> > + }
> > + mod->release_ref();
> > + cg->release_ref();
> > +
> > + wchar_t* m = cci->errorMessage();
> > + if (wcscmp(m, L""))
> > + {
> > + printf("Error generating code: %S\n", m);
> > + cci->release_ref();
> > + free(m);
> > + return -1;
> > + }
> > + free(m);
> > +
> > + // We now have the code information...
> > + WriteCode(cci);
> > + cci->release_ref();
> > +
> > + return 0;
> > +}
> >
> > Modified: CellML_DOM_API/trunk/CCGS/tests/build.mk
> > ===================================================================
> > --- CellML_DOM_API/trunk/CCGS/tests/build.mk 2009-01-07 01:57:04
UTC
> (rev
> 2990)
> > +++ CellML_DOM_API/trunk/CCGS/tests/build.mk 2009-01-08 03:29:51
UTC
> (rev
> 2991)
> > @@ -1,4 +1,4 @@
> > -bin_PROGRAMS += CellML2C CellML2Python
> > +bin_PROGRAMS += CellML2C CellML2Python CellML2Matlab
> > CellML2C_SOURCES=$(top_srcdir)/CCGS/tests/CellML2C.cpp
> > CellML2C_LDADD=\
> > $(top_builddir)/libcellml.la \
> > @@ -11,3 +11,9 @@
> > $(top_builddir)/libccgs.la -lxml2
> > CellML2Python_LDFLAGS=-O0
> > CellML2Python_CXXFLAGS=-I$(top_srcdir)/sources
> -I$(top_srcdir)/sources/dom -I$(top_srcdir)/sources/mathml
> -I$(top_srcdir)/sources/cellml -I$(top_srcdir)/AnnoTools/sources
> -I$(top_builddir)/interfaces -I$(top_srcdir)/CCGS/sources
> -I$(top_srcdir)/MaLaES/sources -Wall -O0 $(AM_CXXFLAGS)
> > +CellML2Matlab_SOURCES=$(top_srcdir)/CCGS/tests/CellML2Matlab.cpp
> > +CellML2Matlab_LDADD=\
> > + $(top_builddir)/libcellml.la \
> > + $(top_builddir)/libccgs.la -lxml2
> > +CellML2Matlab_LDFLAGS=-O0
> > +CellML2Matlab_CXXFLAGS=-I$(top_srcdir)/sources
> -I$(top_srcdir)/sources/dom -I$(top_srcdir)/sources/mathml
> -I$(top_srcdir)/sources/cellml -I$(top_srcdir)/AnnoTools/sources
> -I$(top_builddir)/interfaces -I$(top_srcdir)/CCGS/sources
> -I$(top_srcdir)/MaLaES/sources -Wall -O0 $(AM_CXXFLAGS)
> >
> > _______________________________________________
> > automated-notifications mailing list
> > automated-notifications at cellml.org
> > http://www.cellml.org/mailman/listinfo/automated-notifications
> >
>
> _______________________________________________
> cellml-tools-developers mailing list
> cellml-tools-developers at cellml.org
> http://www.cellml.org/mailman/listinfo/cellml-tools-developers
>
> _______________________________________________
> cellml-tools-developers mailing list
> cellml-tools-developers at cellml.org
> http://www.cellml.org/mailman/listinfo/cellml-tools-developers





Archive powered by MHonArc 2.6.18.

Top of page