「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}}
 ]

複雑なデータの読み取り

生データファイルが

#コメント
#コメント
#コメント …
データ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]]

関数の頭文字を大文字にしなければならないとか、引数を[]でくくるとか、いろいろと文法が特殊である。