- 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.