Wie wäre es mit so etwas?
restart:
with(CodeGeneration):
with(LanguageDefinition):
LanguageDefinition:-Define("NewC", extend="C",
AddFunction("piecewise", anything::numeric,
proc()
local i;
Printer:-Print("((",_passed[1],") ? ",_passed[2]);
for i from 3 to _npassed-2 by 2 do
Printer:-Print(" : (",_passed[i],") ? ",_passed[i+1]);
end do;
Printer:-Print(" : ",_passed[_npassed],") ");
end proc,
numeric=double)
);
myp:=proc(x::numeric) local result::numeric;
result := piecewise(x>3,3*x,x>2,2*x,x>1,1*x,0);
end proc:
Translate(myp, language="NewC");
double myp (double x)
{
double result;
result = ((0.3e1 < x) ? 0.3e1 * x : (0.2e1 < x) ? 0.2e1 * x : (0.1e1 < x) ? x : 0) ;
return(result);
}
Es stellt sich heraus, dass Codegenerierung [C] [bearbeitet, um das Material zum hinzufügen] piecewise
tut verarbeiten, aber nur, wenn die optimize
Option geliefert wird. (Ich werde einen Fehlerbericht einreichen, dass sie standardmäßig behandelt werden soll.)
restart:
with(CodeGeneration):
with(LanguageDefinition):
myp:=proc(x::numeric) local result::numeric;
result:=piecewise(x>3,3*x,x>2,2*x,x>1,1*x,0);
end proc;
myp := proc(x::numeric)
local result::numeric;
result := piecewise(3 < x, 3*x, 2 < x, 2*x, 1 < x, x, 0)
end proc;
Translate(myp, language="C", optimize);
double myp (double x)
{
double result;
double s1;
if (0.3e1 < x)
s1 = 0.3e1 * x;
else if (0.2e1 < x)
s1 = 0.2e1 * x;
else if (0.1e1 < x)
s1 = x;
else
s1 = 0.0e0;
result = s1;
return(result);
}
Wie Sie sehen können, ist piecewise
behandelt oben durch Übersetzung in einen separaten if(){..}
Block, mit Zuordnung zu einem eingeführt temporären Variable. Dieses Temporär wird anschließend überall dort verwendet, wo der Aufruf piecewise
in der Maple-Prozedur existiert. Und das temporäre wird erklärt. Nett und automatisch. So könnte das für Ihre Verwendung von piecewise
ausreichen.
Sie haben auch gefragt, wie Sie solche temporären Variablen in Ihren eigenen Erweiterungen einführen und deklarieren könnten (wenn ich Sie richtig verstehe). In der gleichen Maple-Session von oben fortgefahren, hier sind einige Ideen in dieser Richtung. Ein nicht zugewiesener globaler Name wird generiert. Die Prozedur myp
wird in eine inerte Form gebracht, zu der die neue lokale Variable hinzugefügt wird. Und dann wird diese veränderte inerte Form wieder zu einem tatsächlichen Vorgang gemacht. Zur Veranschaulichung habe ich eine modifizierte Version Ihrer ursprünglichen Erweiterung verwendet, um piecewise
zu behandeln. Dies alles erzeugt etwas, das nahezu akzeptabel ist. Der einzige Haken ist, dass die Zuweisungsanweisung,
result = temporary_variable;
ist fehl am Platz! Es liegt vor dem piecewise
Übersetzungsblock. Ich sehe noch nicht, wie ich das in der Methode reparieren kann.
LanguageDefinition:-Define("NewC", extend="C",
AddFunction("piecewise", anything::numeric,
proc()
global T;
local i, t;
t:=convert(T,string);
Printer:-Print(t,";\n");
Printer:-Print(" if (",_passed[1],
")\n { ",t," = ",_passed[2],"; }\n");
for i from 3 to _npassed-2 by 2 do
Printer:-Print(" else if (",_passed[i],")\n { ",
t," = ",_passed[i+1],"; }\n");
end do;
Printer:-Print(" else { ",t," = ",_passed[_npassed],"; }");
end proc,
numeric=double)
):
T:=`tools/genglobal`('s'):
newmyp := FromInert(subsindets(ToInert(eval(myp)),'specfunc(anything,_Inert_LOCALSEQ)',
z->_Inert_LOCALSEQ(op(z),
_Inert_DCOLON(_Inert_NAME(convert(T,string)),
_Inert_NAME("numeric",
_Inert_ATTRIBUTE(_Inert_NAME("protected",
_Inert_ATTRIBUTE(_Inert_NAME("protected")
))))))));
newmyp := proc(x::numeric)
local result::numeric, s::numeric;
result := piecewise(3 < x, 3*x, 2 < x, 2*x, 1 < x, x, 0)
end proc;
Translate(newmyp, language="NewC");
double newmyp (double x)
{
double result;
double s;
result = s;
if (0.3e1 < x)
{ s = 0.3e1 * x; }
else if (0.2e1 < x)
{ s = 0.2e1 * x; }
else if (0.1e1 < x)
{ s = x; }
else { s = 0; };
return(result);
}
Wenn Sie die letzten drei Aussagen über (aus der Zuordnung zu T
, bis zum Translate
Anruf) erneut ausführen, dann sollten Sie eine neue temporäre Variable verwendet, wie s0 sehen. Und dann s1 wenn noch einmal wiederholt. Und so weiter.
Vielleicht gibt Ihnen das mehr Ideen, mit denen Sie arbeiten können. Prost.
Dies funktioniert natürlich und ist wahrscheinlich die beste Lösung für die stückweise Funktion. Aber was kann ich im allgemeinen Fall tun, wo ich einige Zwischenberechnungen machen muss, um eine Funktion in der C-Sprache zu bewerten? Wie kann ich gültige Variablennamen erhalten? – highsciguy