x,y,zのデータリストを作成して3次元プロットを描きたいとき、
t3 = Table[{x, y, Mod[x, y]}, {x, 30}, {y, 20}]
とするとリストのリストのリストになってしまい({}が一つ多い)プロットできない。
Flatten[t3,1]
で平坦化してやると解決した。
「Mathematica」カテゴリーアーカイブ
PlotLog3D
表題の関数は存在しないが、目盛りを定義することでそれっぽいことはできる。
tickPositions = FindDivisions[{Log[10, .0001], Log[10, 1.]}, 4]; tickLabels = 10.0^tickPositions; tickStructure = Table[{tickPositions[[i]], tickLabels[[i]]}, {i, 1, Length[tickPositions]}]; Plot3D[f[x, y], {x, -1, 1}, {y, Log[10, .0001], Log[10, 1]}, Ticks -> {Automatic, tickStructure, Automatic}]
だが、結局軸が対数グラフっぽくなるわけではないのが惜しい。
NumericQ
FindFitのアルゴリズムでは、本来非線形なモデルをフィットするものではあるが、初めに関数の変数、パラメータ変数の導関数を求めようとする。それらの変数についての微分が定義できないような、複雑なモデル式を使ってフィットしたいときは、関数を定義する際、該当する変数の後に?NumericQをつければよい。引数として数値以外は受け付けませんよという意味になる。その場合、予測精度が悪くなり、そのためフィッティングの試行回数も大幅に増えるので、良いinitial guessを用意できるとよい。
リストの統合、分割
ListPlotで色分けを行うためには、(単一の)リストではなくネストしたリスト(リストのリスト)の方が都合が良いが、フィッティングを行うには単一のリストを与える必要がある。Join[list1,list2]で、list1にlist2の全要素を追加できる。
Table関数でループ変数を2つ以上に増やすとネストしたリストができる。
Flatten[list,rank]でネストしたリストを平坦化することができる。
Partition[list,n]でサブリストに分割することができる。
特定の数に対するループ
特に規則的に続くわけではない数についてループしたい時は、次のようにするとできる。処理が複雑でなければ、Table関数でも可。直観的にはForループでもできるようにしてほしかったが、ループ変数に対するincrを設定する必要があるため、無理?
Do[ 処理式 {i, {5, 10, 20}} ]
変数名をファイル名に使う
T = 300; tmp = Import["/koko/doko/iv_" <> ToString[T] <> "K.txt", "Data"];
複雑なデータの読み取り
生データファイルが
#コメント
#コメント
#コメント …
データ1a データ2a データ3a
データ1b データ2b データ3b
データ1c データ2c データ3c
…
のように並んでいて、さらにデータ3をx軸、データ2をy軸としてプロットやフィッティングを行いたいとする。
Gnuplotならコメントは自動的に飛ばしてくれるし、
plot “ファイル名” u 3:2
で一発だが、Mathematicaではそう簡単にはいかない。
まずデータをすべて読み込み、要素数が3かつそのすべてが数値データであるリストのみを抽出し、新たにTableを定義すれば、そのままプロットできるデータリストが手に入る。
tmp = Import["パス付きのファイル名", "Data"]; tmp2 = Cases[tmp, {_?NumericQ, _?NumericQ, _?NumericQ}, Infinity]; datax = tmp2[[All, 3]]; datay = tmp2[[All, 2]]; iv = Table[{datax[[i]], datay[[i]]}, {i, 1, Length[datax]}];
複雑な関数の定義
Mathematicaの例題には一文程度の短い関数が多いが、複雑な関数を定義したいこともある。そんな場合は、次のように書く。Module[{},の{}の中身はローカル変数。Mathematicaの変数は基本的にグローバル変数であり、外で定義した変数は関数内部でも用いることができる。外に出したくない変数だけをここで指定する。
function[a_, b_] := Module[{ans,t}, t=Exp[a] ans=t+b; Return[ans]; ];
数行で済む場合は、
function[a_, b_] := (t =Exp[a];t+b )
という書き方もある。
IV曲線
[latex] J=J_0T^{1+\alpha} \sinh(\gamma\frac{eV}{kT})|\Gamma(1+\frac{\alpha}{2}+i\gamma\frac{eV}{\pi kT})|^2[/latex]
このIV曲線の式を使ってデータをフィットしようとしたところ、ガンマ関数の引数が複素数になっているのがやっかいだと判明。GnuplotやOriginでは、ガンマ関数の引数は実数しかとれない。しかし、Mathematicaならできるようだ。
model = val1*T^(1 + val2) * Sinh[val3 * x / k / T]* Abs[Gamma[1 + val2/2 + I*val3*x/Pi/k/T]] fit = FindFit[iv, model, {val1, val2, val3}, x] Show[Plot[Evaluate[model /. fit], {x, -1, 1}, Frame -> True], ListPlot[iv, PlotStyle -> Red]]
関数の頭文字を大文字にしなければならないとか、引数を[]でくくるとか、いろいろと文法が特殊である。