Matlab2Cellml
Perl package containg functions Eqn2Cellml and kern2cellml. Eqn2Cellml takes a sting containing a single line Eqn written in matlab format and returns a sting out containg the CellML code for that Eqn. kern2cellml is called by Eqn2cellml and takes a braketed kernal and generates the cellml code.
Size 6.7 kB - File type text/x-perlFile contents
package MatLab2CellML;
#---------------------------------------------------------------------
sub Eqn2Cellml {
#Given an equation $line will convert that line into cellml
#requires kern2cellml
#Initialise variables
my $line = @_[0];
my $var;
my $Equation;
my $k;
my $out;
my $go;
my $kernal;
my @kernals;
my $i;
my $kern;
#Split equation into variable and equation
($var, $Equation) = split(/=/,$line);
#celan
$Equation =~ s/[;\n]//g;
$var =~ s/\s//g;
#Initialise equation
$out = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"> \n<apply id=\"$var\_Eqn\"><eq /> \n <ci> $var </ci> \n :spacer: \n </apply> \n </math> \n";
#Initialis kernal count
$k = 1;
#unrap eqn into kernals
$go = 1;
while ($go == 1) {
#remove brakets and put contents of braket into kernal i
if ($Equation =~ /\([\w \_ \. \* \- \/ \+ \^ \s]*\)/) {
#find first kernal and store in 1
$Equation =~ s/(\([\w \* \_ \. \- \/ \+ \^ \s]*\))/\1/;
#replace kernal with kernal and number as spacer
$Equation =~ s/(\([\w \* \_ \. \- \/ \+ \^ \s]*\))/kernal$k/;
#store kernal in one and strip it of its brackets
$kernal = $1;
$kernal =~ s/[\(\)]//g;
} else {
#If no more brakets decompose remaining eqn
$kernal = $Equation;
$go = 0;
};
$k = $k +1;
#convert the kernal to cellml
$kernal = &MatLab2CellML::kern2Cellml($kernal);
push(@kernals,$kernal);
};
$kern = pop(@kernals);
$out =~ s/:spacer:/ $kern \n/;
$i = $k-2;
while ($kern = pop(@kernals)) {
$out =~ s/<ci>\s*kernal$i\s*<\/ci>/$kern/;
$i = $i -1;
};
$out =~ s/<ci>\s*([0-9]*[\.e]?[0-9]*[\.e]?[0-9]*[\.e]?[0-9]*)\s*<\/ci>\s*\n/<cn cellml:units=\"dimensionless\"> $1 <\/cn> \n/g;
$out =~ s/\n\s*\n/\n/g;
$out ="$out\n";
return($out);
};
sub kern2Cellml {
#Sub converts a kernal (ie a function that contains no brakets) into cellml
my ($kernal) =@_;
my $iexp;
my $temp;
my @ExpS;
my $ilog;
my @LogS;
my $iln;
my @LnS;
my $iE;
my @PowerS;
my $iD;
my @DivideS;
my @NegativeS;
my $iS;
my @TimesS;
my $iM;
my $iA;
my $PlusS;
my @MinusS;
my $iSS;
my $cellml;
#replace minus sfunctions with & where they are minus signs
if ($kernal =~ /^\-/) {
$kernal =~ s/^\-/\&/;
};
$kernal =~ s/([\-\*\/\(\^])\-/\1\&/g;
#decompose in order of operations
$iexp = 1;
while ($kernal =~ /expkernal/) {
$kernal =~ s/exp(kernal\d+)/exp\1/;
$temp = "<apply><exp /> \n<ci> $1 </ci>\n <\/apply>\n";
push(@ExpS,$temp);
$kernal =~ s/exp(kernal\d+)/ExpOperator$iexp/;
$iexp = $iexp + 1;
};
$iexp = $iexp - 1;
$ilog = 1;
while ($kernal =~ /logkernal/) {
$kernal =~ s/log(kernal\d+)/log\1/;
$temp = "<apply><log /> \n <ci> $1 </ci>\n <\/apply>\n";
push(@LogS,$temp);
$kernal =~ s/log(kernal\d+)/LogOperator$ilog/;
$ilog = $ilog + 1;
};
$ilog = $ilog - 1;
$iln = 1;
while ($kernal =~ /lnkernal/) {
$kernal =~ s/ln(kernal\d+)/ln\1/;
$temp = "<apply><ln /> \n <ci> $1 </ci>\n <\/apply>\n";
push(@LnS,$temp);
$kernal =~ s/ln(kernal\d+)/LnOperator$iln/;
$iln = $iln + 1; my $tab =" ";
};
$iln= $iln - 1;
$iE = 1;
while ($kernal =~ /\^/) {
$kernal =~ s/([\w \_ \.]*)(\^)([\w \_ \.]*)/\1\2\3/;
$temp = "<apply><power /> \n <ci> $1 </ci>\n<ci> $3 </ci>\n <\/apply>\n";
push(@PowerS,$temp);
$kernal =~ s/$1\^$3/PowerOperator$iE/;
$iE = $iE + 1;
};
$iE = $iE - 1;
$iD = 1;
while ($kernal =~ /\//) {
$kernal =~ s/([\w \_ \.]*)(\/)([\w \_ \.]*)/\1\2\3/;
$temp = "<apply><divide /> \n <ci> $1 </ci>\n<ci> $3 </ci>\n <\/apply>\n";
push(@DivideS,$temp);
$kernal =~ s/$1\/$3/DivideOperator$iD/;
$iD = $iD + 1;
};
$iD = $iD - 1;
$iS = 1;
while ($kernal =~ /\&/) {
$kernal =~ s/\&([\w \_ \.]*)/\&\1/;
$temp = "<apply><minus /> \n <ci> $1 </ci>\n<\/apply>\n";
push(@NegativeS,$temp);
$kernal =~ s/\&([\w \_ \.]*)/NegativeSign$iS/;
$iS = $iS + 1;
};
$iS = $iS - 1;
$iM = 1;
while ($kernal =~ /([\w \_ \.]*)(\*)([\w \_ \.]*)/) {
$kernal =~ s/([\w \_ \.]*)(\*)([\w \_ \.]*)/\1\2\3/;
$temp = "<apply><times /> \n <ci> $1 </ci>\n<ci> $3 </ci>\n <\/apply>\n";
push(@TimesS,$temp);
$kernal =~ s/$1\*$3/TimesOperator$iM/;
$iM = $iM + 1;
};
$iM = $iM -1;
$iA = 1;
while ($kernal =~ /\+/) {
$kernal =~ s/([\w \_ \.]*)(\+)([\w \_ \.]*)/\1\2\3/;
$temp = "<apply><plus/> \n <ci> $1 </ci>\n<ci> $3 </ci>\n <\/apply>\n";
push(@PlusS,$temp);
$kernal =~ s/$1\+$3/PlusOperator$iA/;
$iA = $iA + 1;
};
$iA = $iA - 1;
$iSS = 1;
while ($kernal =~ /\-/) {
$kernal =~ s/([\w \_ \.]*)(\-)([\w \_ \.]*)/\1\2\3/;
$temp = "<apply><minus/> \n <ci> $1 </ci>\n <ci> $3 </ci>\n <\/apply>\n";
push(@MinusS,$temp);
$kernal =~ s/$1\-$3/MinusOperator$iSS/;
$iSS = $iSS + 1;
};
$iSS = $iSS - 1;
$kernal =~ s/^/<ci> /;
$kernal =~ s/$/ <\/ci> \n/;
#REbuild in Cellml order
while ($cellml = pop(@MinusS)) {
$kernal =~ s/<ci>\s*MinusOperator$iSS\s*<\/ci>\s*\n/$cellml/;
$iSS = $iSS - 1;
};
while ($cellml = pop(@PlusS)) {
$kernal =~ s/<ci>\s*PlusOperator$iA\s*<\/ci>\s*\n/$cellml/;
$iA = $iA - 1;
};
while ($cellml = pop(@TimesS)) {
$kernal =~ s/<ci>\s*TimesOperator$iM\s*<\/ci>\s*\n/$cellml/;
$iM = $iM - 1;
};
while ($cellml = pop(@NegativeS)) {
$kernal =~ s/<ci>\s*NegativeSign$iS\s*<\/ci>\s*\n/$cellml/;
$iS = $iS - 1;
};
while ($cellml = pop(@DivideS)) {
$kernal =~ s/<ci>\s*DivideOperator$iD\s*<\/ci>\s*\n/$cellml/;
$iD = $iD - 1;
};
while ($cellml = pop(@PowerS)) {
$kernal =~ s/<ci>\s*PowerOperator$iE\s*<\/ci>\s*\n/$cellml/;
$iE = $iE - 1;
};
while ($cellml = pop(@LnS)) {
$kernal =~ s/<ci>\s*LnOperator$ilnp\s*<\/ci>\s*\n/$cellml/;
$iln = $iln - 1;
};
while ($cellml = pop(@LogS)) {
$kernal =~ s/<ci>\s*LogOperator$ilog\s*<\/ci>\s*\n/$cellml/;
$ilog = $ilog - 1;
};
while ($cellml = pop(@ExpS)) {
$kernal =~ s/<ci>\s*ExpOperator$iexp\s*<\/ci>\s*\n/$cellml/;
$iexp = $iexp - 1;
};
#Search for numbers in eqautions and replace with cellml numbers
$kernal =~ s/<ci>\s*([0-9]*[\.\e]?[0-9]*[\.\e]?[0-9]*[\.\e]?[0-9]*)\s*<\/ci>\s*\n/<cn cellml:units=\"dimensionless\"> $1 <\/cn> \n/g;
return($kernal);
};
1;
__END__
