這樣的事情呢?
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);
}
[編輯,添加下面的材料]
事實證明,CodeGeneration [C]不處理piecewise
,但只有當optimize
選項被提供。 (我將提交錯誤報告,它應該在默認情況下進行處理。)
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);
}
正如你所看到的,piecewise
被翻譯上述處理到一個單獨的if(){..}
塊,以分配給引入的臨時變量。隨後在Maple過程中存在調用piecewise
的地方使用該臨時值。臨時宣佈。尼斯和自動。所以這可能足以讓您使用piecewise
。
你也問過你如何在你自己的擴展中引入和聲明這樣的臨時變量(如果我理解你的話)。繼續從上面的同一個楓樹會議,這裏有一些想法。生成未分配的全局名稱。將myp
過程置於惰性形式,將新局部變量添加到該形式。然後,改變後的惰性形式被轉變回實際的程序。作爲說明,我使用了原始擴展的修改版本來處理piecewise
。這一切都產生了接近可接受的東西。唯一的障礙是,轉讓聲明,
result = temporary_variable;
是不合適的!它位於piecewise
翻譯塊之前。我還沒有看到如何修復該方法。
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);
}
如果重新運行上面的最後三個報表(從分配到T
,通過對Translate
呼叫),那麼你應該可以看到使用了新的臨時變量,如S0。然後再次重複s1。等等。
也許這會給你更多的想法。乾杯。
這當然是有效的,並且可能是分段函數的最佳解決方案。但是,在我需要做一些中間計算來評估C語言函數的一般情況下,我能做些什麼呢?我如何獲得有效的變量名稱? – highsciguy 2012-04-10 13:51:39