入力 Total[{a,b,c}]
出力 a+b+c
入力 {a,b,c}/.List->Times
出力 a*b*c
入力 Accumulate[{a,b,c}]
出力 {a,a+b,a+b+c}
入力 RotateLeft[{a,b,c}]
出力 {b,c,a}
入力 RotateRight[{a,b,c}]
出力 {c,a,b}
入力 {a,b,c}+x
出力 {a+x,b+x,c+x}
入力 {a,b,c}*x
出力 {a*x,b*x,c*x}
入力 {a,b,c}+{x,y,z}
出力 {a+x,b+y,c+z}
入力 {a,b,c}*{x,y,z}
出力 {a*x,b*y,c*z}
入力 {{a,b,c},{d,e,f}}*{{x,y,z},{u,v,w}}
出力 {{a*x,b*y,c*z},{d*u,e*v,f*w}}
入力 Map[Total,{{a,b,c},{d,e,f}}*{{x,y,z},{u,v,w}}]
出力 {a*x+b*y+c*z,d*u+e*v+f*w}
入力 Map[f,{a,b,c}]
出力 {f[a],f[b],f[c]}
入力 Apply[f,{a,b,c}]
出力 f[a,b,c]
入力 Thread[List[x,{a,b,c}]]
出力 {{x,a},{x,b},{x,c}}
入力 Thread[List[{a,b,c},x]]
出力 {{a,x},{b,x},{c,x}}
入力 MapThread[List,{{a,b,c},{x,y,z}}]
出力 {{a,x},{b,y},{c,z}}
入力 Through[{f,g,h}[a]]
出力 {f[a],g[a],h[a]}
入力 Thread[f[{a,b,c},x]]
出力 {f[a,x],f[b,x],f[c,x]}
入力 Thread[f[x,{a,b,c}]]
出力 {f[x,a],f[x,b],f[x,c]}
入力 Thread[f[{a,b,c},{x,y,z}]]
出力 {f[a,x],f[b,y],f[c,z]}
入力 Apply[f,{{a,x},{b,y},{c,z}},1]
出力 {f[a,x],f[b,y],f[c,z]}
入力 Map[Through,Thread[{f,g}[{a,b,c}]]]
出力 {{f[a],g[a]},{f[b],g[b]},{f[c],g[c]}}
入力 Replace[{{a,b,c},{x,y,z}},List->f,1,Heads->True]
出力 f[{a,b,c},{x,y,z}]
入力 Thread[{x,y,z}=={a,b,c}]
出力 {x==a,y==b,z==c}
入力 Operate[g,f[a,b]]
出力 g[f][a,b]
HD[listofvars_,listofnums_][f_,g_]:= Module[{var,num,max,index,currentvar},
var=listofvars;
num=listofnums;
max=Length[var];
index=1;
currentvar=var[[index]];
If[max!=Length[num],Return[],If[num==Table[0,max],Return[f*g],
While[index<=max,
(*starting main part*)
While[num[[index]]>0,
num=ReplacePart[num,index->num[[index]]-1];
Return[HD[var,num][D[f,currentvar],g]-HD[var,num][f,D[g,currentvar]]]];
(*ending main part*)
index++;
currentvar=var[[index]];]]]];
と書けばよい。使い方は、もし \(D_x^2\, f\cdot g\) を計算したければ
HD[{x},{2}][f[x],g[x]]
とし、あるいはもし \(D_t D_x^2\, f\cdot g\) を計算したければ
HD[{x,t},{2,1}][f[x,t],g[x,t]]
とする。
=と遅延定義
:=でたとえば
a[x_]=D[x^2,x]; b[x_]:=D[x^2,x];と書いたとき
a[2]の値は正しく
4と表示されるが
b[2]の評価はエラーになる。後者を評価したい場合は
b[x]/.x->2と書く。一般に、関数を定義するときは、もしそれが即時定義で書けるのなら即時定義で書いておくほうが都合のよいことが多い。
line[pt1_,pt2_]:=Module[{midpt,diff},
midpt=1/2*(pt1+pt2);
diff=pt2-pt1;
diff[[2]]*(y-midpt[[2]])==-diff[[1]]*(x-midpt[[1]])
]
と書ける。もしこれを即時定義で
line[pt1_,pt2_]=Module[{midpt,diff},
midpt=1/2*(pt1+pt2);
diff=pt2-pt1;
diff[[2]]*(y-midpt[[2]])==-diff[[1]]*(x-midpt[[1]])
]
書いてしまうと、期待通りの出力が得られない。なぜなら、この書き方では引数pt1,
pt2をベクトルだと宣言していないため
midpt[[1]],
midpt[[2]],
diff[[1]],
diff[[2]]がまったく異なる意味に解釈されてしまうため。
Evaluateしておくとよい。たとえば
f[x_]:=Integrate[Exp[-t^2],{t,0,x}];
g[x_]:=Evaluate[Integrate[Exp[-t^2],{t,0,x}]];
{Timing[Do[f[k],{k,0,100}]],Timing[Do[g[k],{k,0,100}]]}
の実行結果は {{0.505576,Null},{0.000298,Null}} などとなり、このように実行時間にかなりの差が生じうる。
NIntegrateを使うとき、評価の順番が大切になることがある。たとえば
f[a_]:=NIntegrate[(2-a)*Sin[a*x],{x,0,Pi}]
と書くと f[0.5]は計算できるが
f[a]はエラーとなる。したがって例えば
NMaximize[f[a],a]のように関数
fを数値的に最大化することができなくなってしまう。計算の順序をコントロールするには、
NumericQとパターンのテストを使って、関数
fが数値を受けとった場合にのみこれを評価するように定義する。すなわち
f[a_?NumericQ]:=NIntegrate[(2-a)*Sin[a*x],{x,0,Pi}]
とする。このとき f[a]を評価すると関数が未評価のまま返されるので、したがって例えば
NMaximize[f[a],a]のように数値的に最大化することができるようになる。
NIntegrateの評価を高速化する方法は、被積分関数の性質による。 一般には
NIntegrateのオプション
"SymbolicProcessing"を
0に設定し、積分を記号的に操作しないようにすると高速に評価できる場合がある。
NIntegrate[f[x],{x,0,1},Method->{Automatic,"SymbolicProcessing"->0}]
あるいはもし被積分関数に特異点があれば Exclusionsオプションで教えておくとよい。
NIntegrate[1/Sqrt[Sin[x]],{x,0,10},Exclusions->Sin[x]==0]
kappa[s_]=Sin[Cos[s]];
init=0;
theta[s_?NumericQ]:=NIntegrate[kappa[ss],{ss,init,s},Method->{Automatic,"SymbolicProcessing"->0}];
gamma[s_?NumericQ]:=Module[{xcoord,ycoord},
xcoord=NIntegrate[Cos[theta[ss]],{ss,init,s},Method->{Automatic,"SymbolicProcessing"->0}];
ycoord=NIntegrate[Sin[theta[ss]],{ss,init,s},Method->{Automatic,"SymbolicProcessing"->0}];
{xcoord,ycoord}];
ParametricPlot[gamma[s],{s,init,2*Pi}]
と書けばよい。
NIntegrateは使いづらい)、最初から微分方程式系として書いておき、その数値解法には
NDSolveを使えばいいんじゃないかな。
PlotPoints->100,
PlotRange->{{-5,5},{-5,5}},
Ticks->{Table[n,{n,-5,5}],Table[n,{n,-5,5}]},
Axes->True,
AxesOrigin->{0,0},
PlotStyle->Black,
AxesStyle->Black,
PlotLabel->None,
LabelStyle->{GrayLevel[0],Bold}
などを付ける。原稿を実際に印刷して、とくに座標軸や目盛りが濃くはっきりと印字できているか確認すること。
dsolveを使うとき、