「gnuplot」カテゴリーアーカイブ

gnuplotで、あるディレクトリ内にある全てのファイルをプロットする

まとめ


gnuplotで、ディレクトリ(dat)内にある全てのファイルをプロットするには、

fnames=system("/bin/ls ./dat/*")
plot for[fn in fnames] sprintf("%s",fn) u 1:2

とすればいいです。

状況


いま、ディレクトリの構造が

.
└── dat
    ├── a.d
    ├── b.d
    └── c.txt

となっているとします。ここで、datはプロットしたいデータ(a.d、b.dとc.txt)が入っているディレクトリです。
この時、gnuplot上で

fnames=system("/bin/ls ./dat/*")
plot for[fn in fnames] sprintf("%s",fn) u 1:2

と入力すれば、ディレクトリdat内にある全てのファイルがプロットされます。

また、拡張子.dにあてはまるものだけをプロットしたければ、

fnames=system("/bin/ls ./dat/*.d")
plot for[fn in fnames] sprintf("%s",fn) u 1:2

とすればいいです。

gnuplotで平均と分散を表示する

gnuplotで平均、分散を表示します。
このページのゴールは↑のアイキャッチ画像を得ることを目的にします。

持ってるもの

・ファイル名”qwerty.d”に格納された1列目x、2列目y(x)のデータ。

gnuplotを用いて出力するもの

・平均、分散の表示

コマンド
stats "qwerty.d" u 1:2 name "qw" nooutput

plot "qwerty.d" u 1:2 pt 7 ps 1,\
      qw_mean_y lw 3 lt 1 lc 1 notitle,\
      qw_mean_y+qw_stddev_y lt 2 lc 1 notitle,\
      qw_mean_y-qw_stddev_y lt 2 lc 1 notitle

とすれば以下の画像が得られます。

真ん中の黒い実線が平均値、上下の黒の点線は平均値±標準偏差を表します。
データが正規分布に従うのであれば、真値(この場合は平均値=真値を仮定)を中心に約68%が上下の点線内に入ります。

gnuplotで複数の図を載せる

gnuplotで複数の図を載せたい時はmultiplotを使います。

うまくmultiplotを使いこなすポイントは、
・1つ1つの図の上下左右の絶対位置を指定する
・eps画像のサイズを決定する
・トライ&エラー
です。

multiplotとは


multiplotとは、その名の通り複数の図を同時にgnuplot上で表示させることです。
これを使うと、図同士の比較が出来たり、insetを入れることが出来るようになります。

さて、gnuplotには標準で横2行×縦3列など決まったレイアウトのmultiplotが出来る

set multiplot layout 2,3

というコマンドが存在しますが、ここではlayoutは使いません。
なぜなら、グラフの細かい調整が出来ないからです。例えば、2つの図でx軸を共有させたい場合がありますがこれはlayoutを使うと出来ません。なので、これに頼らない方法を紹介します。

2枚の図を同時に表示させたいとします。
この時、2枚の図の位置を、

set lmargin screen 0.3
set rmargin screen 0.9
set tmargin screen 0.9
set bmargin screen 0.7

のように指定します。lmarginなどは↓の図位置の長さを指定しています。

座標は絶対位置で、左下を座標(x,y)=(0,0)にとり、右上を(x,y)=(1,1)として考えます。

座標(1,1)は出力形式で設定したサイズを表しています。
例えば、サイズを横3インチ、縦5インチに設定した場合、座標(0.5,0.5)は横1.5インチ、縦2.5インチの座標を表しています。

これは重要なことです。
今、完成した画像を完全な正方形のグラフにしたいとします。
この時、座標を縦横0.5のサイズを持つようにとったとしても、出力形式のサイズが正方形でない限り完成した図が正方形になることはないことを意味しています。

x軸を共有したい場合


x軸を共有したい場合、
1枚目の画像(青線)のbmargin

2枚目の画像(緑線)のtmargin
を一致させ、lmarginとrmarginを一致させると良いでしょう。
この場合↓の図のように考えます。

実例がこちら。

コードの中身はこんな感じ。

清書

上の図を少し綺麗にしてみました。
書式やticsは引き継がれるので、各々のplotの前にできる限り記述をしたほうが良いでしょう。

縦軸と横軸を共通に


縦軸と横軸を共通にしたい場合はこんな感じにとれば良いです。

実例

コードの中身はこんな感じ。

insetを入れる


注意する点は、2番目のグラフが1番目のグラフの上に来る、ということです。

また、insetは背景を白くするために白色のオブジェクト

set object 1 rect behind from screen 0.3,0.2 to screen 0.6,0.5 fc rgb "#ffffff" fillstyle solid 1.0

を入れています。デフォルトでは透過してしまうためです。

Note


アイキャッチのフォントは “Commune-Round”を用いています。 http://www.gebsite.org/

幾何学模様(gnuplot)

gnuplotで幾何学模様を描きます。

正多角形の組み合わせで幾何学模様を描きます。
gnuplot version5.0以上でないと動きません。

用いるのは正多角形の数式
\(
\begin{equation}
\left\{
\begin{aligned}
x&\displaystyle =\cos t \cdot \frac{\cos \frac{a_n}{2}}{\cos\left[a_n\left\{\frac{t}{a_n}-{\rm floor}\left(\frac{t}{a_n}\right)\right\}-\frac{a_n}{2}\right]}\\
y&\displaystyle =\sin t \cdot \frac{\cos \frac{a_n}{2}}{\cos\left[a_n\left\{\frac{t}{a_n}-{\rm floor}\left(\frac{t}{a_n}\right)\right\}-\frac{a_n}{2}\right]}
\end{aligned}
\right.
\end{equation}
\)
です。ここで、\(a_n=\frac{2\pi}{n}\)、\({\rm floor}(x)\)は床関数(床関数と天井関数)であり、媒介変数\(t\)の範囲は(\(0\le t \lt 2\pi\))です。

正六角形を特に考えましょう。以下のスクリプトを実行することで

set param
set xr[-5:5]
set yr[-5:5]
set tr[0:2*pi]
unset key
set size ratio -1

n=6
# +---polygon---+
s1(x)=x-floor(x)
a(n)=2e0*pi/real(n)
cnp(n,t)=cos(a(n)*s1(t/a(n))-0.5e0*a(n))
pc(n,t)=cos(t)*cos(0.5e0*a(n))/cnp(n,t)
ps(n,t)=sin(t)*cos(0.5e0*a(n))/cnp(n,t)
set samples n*3+1

# +--- geometric pattern ---+
nr=1e0
ix=6
jy=6
xc=0e0
yc=0e0
xr=1e0
yr=sqrt(3e0)
oddshift=0e0
   
plot for[i=-ix:ix]for[j=-jy:jy] \
nr*pc(n,t)+xr*i+xc,\
((i+ix)%2 == 1 ? nr*ps(n,t)+yr*j+oddshift+yc : nr*ps(n,t)+yr*j+yc) lc 1

geoex_c
という画像が得られます。
これは、正六角形の組み合わせで作られており、それを格子状に配置することで幾何学模様を作り出しています。

格子点の配置や正六角形の大きさを変更することで様々な幾何学模様が得られます。
上記スクリプトの変数はそれぞれ
————————-
nr : 正n角形の大きさ(比率)
jx : 格子の列数の半分
jy : 格子の行数の半分
xc : x方向の格子のオフセット
yc : y方向の格子のオフセット
xr : x方向の格子の間隔
yr : y方向の格子の間隔
oddshift : x方向の奇数番目の列に対するy方向のオフセット
————————-
以下はxr,yr,oddshiftの組み合わせによって得られる様々な幾何学模様のパターンです。
geometric0_c
グラフェンっぽいのができますね。
3次元に簡単に拡張できるので、炭素の構造とかも作れます。

もちろん回転させることも可能です。
その場合はスクリプト”setting pattern”以下を

# +--- setting pattern ---+
nr=1e0
ix=6
jy=6
xc=0e0
yc=0e0
xr=1e0
yr=1e0

oddshift=yr/2e0
theta=pi/2e0

plot for[i=-ix:ix]for[j=-jy:jy] \
((i+ix)%2 == 1 ? pc(n,t)*cos(theta)-ps(n,t)*sin(theta)+xr*i+xc : pc(n,t)+xr*i+xc),\
((i+ix)%2 == 1 ? pc(n,t)*sin(theta)+ps(n,t)*cos(theta)+yr*j+yc+oddshift : ps(n,t)+yr*j+yc) lc 1

と変更してください。これは奇数列目のみを回転させる操作です。
適当なパラメータにおいて、
geo6rot_c
という模様が得られます。

また、正n角形全てのパターンを考える事が出来ます。例えば、正七角形の場合、
geo7rot_c
といった模様が得られます。

線とグラデーション(gnuplot)

gnuplotで、線の色を少し変化させながら色を付けていきます。

複数の線をグラデーション


 set linetype  1 lc rgb "#ff0000" lw 1
 set linetype  2 lc rgb "#ff1f1f" lw 1
 set linetype  3 lc rgb "#ff3f3f" lw 1
 set linetype  4 lc rgb "#ff5f5f" lw 1
 set linetype  5 lc rgb "#ff7f7f" lw 1
 set linetype  6 lc rgb "#ff9f9f" lw 1
 set linetype  7 lc rgb "#ffbfbf" lw 1
 set linetype  8 lc rgb "#ffdfdf" lw 1

 set linetype  9 lc rgb "#0000ff" lw 1
 set linetype 10 lc rgb "#1f1fff" lw 1
 set linetype 11 lc rgb "#3f3fff" lw 1
 set linetype 12 lc rgb "#5f5fff" lw 1
 set linetype 13 lc rgb "#7f7fff" lw 1
 set linetype 14 lc rgb "#9f9fff" lw 1
 set linetype 15 lc rgb "#bfbfff" lw 1
 set linetype 16 lc rgb "#dfdfff" lw 1

plot for[i=1:8] 0.2*i*x w l lw 2 lc i lt 1 title sprintf("%d",i)
replot for[i=9:16] -0.2*(i-8)*x w l lw 2 lc i lt 1 title sprintf("%d",i)

を実行すると、
lineg_c
という画像を得ます。

1つの線をグラデーション


set table "d1.d"
plot x
unset table

set table "d2.d"
splot "d1.d" u 1:2:2
unset table

plot "d2.d" u 1:2:3 w l lw 4 lc palette

を実行すると、
line_gra_c
と言うグラフが得られます。縦軸の値に応じた色で付けられます。

gnuplotで点にラベルを付けて出力

gnuplotで点とその点の値を付けたいとします。
数点だけならば、

set label "moji" at 4,0.2

とやれば点(4,0.2)に”moji”という文章が書かれます。

複数点の場合を考えます。
ここでは、データ”test.d”として、

1 0.1
2 0.2
3 0.3
4 0.4
5 0.5
6 0.6
7 0.7

を考えます。gnuplot単体でやることはできないと思います。
若干作業しなければなりません。

ファイル”test.plt”を生成し、中に以下の文を書きます。

unset label

!perl -ane 'print "set label sprintf("\%6.4f",$F[1]) at $F[0]-0.05,$F[1]+0.04\n"' test.d > p.plt

load "p.plt"
plot "test.d" pt 7

とすると各点の位置からx軸方向に-0.05, y軸方向に+0.04ずれた位置にその点のy軸の値が出力されます。gnuplot上で上のファイルを読み込むと以下の出力を得ます。
point_label

参考文献
Basic statistics with gnuplot

gnuplotである1つの点のみを表示する

gnuplotで複数行から成るデータの第n行目だけを点としてプロットしたい場合があります。

例えば、全100行から成るデータ(“data.d”)の第17行目だけをプロットしたいとします。
この時、

plot "data.d" every ::17:0:17:0 u 1:2

とすれば、第17行目だけが点としてプロットされます。

その他、例えばデータではなく、ある関数のf(x)のx=5.7の時だけの値をプロットしたい時は

plot sprintf("< echo ''%f %f''", 5.7,f(5.7))

とすればよいです。

例1

データ”test.d”として

1 0.1
2 0.2
3 0.3
4 0.4
5 0.5
6 0.6
7 0.7

を考えます。この時gnuplot上で、

plot "test.d" every ::5:0:5:0 pt 7

と行うと
pointevery
というグラフが得られます。

例2

sin(5.7)を考えます。gnuplot上で

plot sprintf("< echo ''%f %f''", 5.7,sin(5.7)) pt 7

とすれば
point_function
という画像を得ます。都合上同時にsin(x)も出力しています。

参考文献
 複数のデータファイルのある列の差分表示 -計算機は楽し
gnuplotのコマンドまとめ(ループとかeveryとか) -Linux, Mac, Emacsについての設定、覚え書き

正多角形とスピログラフの数式

正多角形とスピログラフの数式です。

  1. 正多角形(2次元)
  2. 正多角形(3次元)
  3. 星型多角形(2次元)
  4. 星型多角形(3次元)
  5. トロコイド(2次元)
  6. トロコイド(3次元)
  7. スピログラフ

2016/10/24
幾何学模様を作りたい方は幾何学模様(gnuplot)へどうぞ。


スポンサーリンク


正多角形の式(2次元)


正n角形の数式は[1]を参考に修正しました。
正n角形の数式は、
\(
\begin{equation}
\left\{
\begin{aligned}
x&\displaystyle =\cos t \cdot \frac{\cos \frac{a_n}{2}}{\cos\left[a_n\left\{\frac{t}{a_n}-{\rm floor}\left(\frac{t}{a_n}\right)\right\}-\frac{a_n}{2}\right]}\\
y&\displaystyle =\sin t \cdot \frac{\cos \frac{a_n}{2}}{\cos\left[a_n\left\{\frac{t}{a_n}-{\rm floor}\left(\frac{t}{a_n}\right)\right\}-\frac{a_n}{2}\right]}
\end{aligned}
\right.
\end{equation}
\)
です。ここで、\(a_n=\frac{2\pi}{n}\)と置きました。また、\({\rm floor}(x)\)は床関数(床関数と天井関数)を表します。
媒介変数\(t\)の範囲は(\(0\le t \lt 2\pi\))です。
グラフを書かせてみますとこうなります。

polygon3_10_c
n=3,4,5,6
n=7,8,9,10の順で、単位円を一緒に記述しています。
線の色の濃さは媒介変数の値に応じて変化させています。

gnuplotのスクリプトはこちら

多面体の式(3次元)


半径1の多面体は、平面のx,yの媒介変数による正n角形の関数をそれぞれpc(t),ps(t)と置くと、
\(
\begin{equation}
\left\{
\begin{aligned}
x& = {\rm ps}(u)\cdot {\rm pc}(v) \\
y& = {\rm ps}(u)\cdot {\rm ps}(v) \\
z& = {\rm pc}(u)
\end{aligned}
\right.
\end{equation}
\)
と書けます。
媒介変数\(u,v\)の範囲は(\(0\le u \lt \pi, \;\; 0\le v \lt 2\pi\))です。

プロットすると以下のようになります。
polygon3d_3_10_c
n=3,4,5,6
n=7,8,9,10の順です。

gnuplotスクリプトはこちら

星型多角形(2次元)


\(
\begin{equation}
\left\{
\begin{aligned}
x&\displaystyle =\cos t \cdot \frac{\cos a_n}{\cos\left[a_n -\frac{1}{n}\cos^{-1}\{\cos(nt)\}\right]}\\
y&\displaystyle =\sin t \cdot \frac{\cos a_n}{\cos\left[a_n -\frac{1}{n}\cos^{-1}\{\cos(nt)\}\right]}
\end{aligned}
\right.
\end{equation}
\)
です(\(n\ge 5\))。ここで、\(a_n=\frac{2\pi}{n}\)と置きました。
グラフを書かせてみるとこのようになります。
starpolygonp_c

gnuplotスクリプトはこちら。
※\(\cos^{-1}(\cos(x))\)は不安定です。
場合により書けなくなることがあります。ここでは上記関数の代わりに、正弦波ではない周期関数の数式
で記述した関数\(s(a,x)\)を用いています。

星型多角形(3次元)


3次元の場合は多面体の時と同じように、平面のx,yの媒介変数による星型多角形の関数をそれぞれstpc(t),stps(t)と置くと、
\(
\begin{equation}
\left\{
\begin{aligned}
x& = {\rm stps}(u)\cdot {\rm stpc}(v) \\
y& = {\rm stps}(u)\cdot {\rm stps}(v) \\
z& = {\rm stpc}(u)
\end{aligned}
\right.
\end{equation}
\)
と書けます。
媒介変数\(u,v\)の範囲は(\(0\le u \lt \pi, \;\; 0\le v \lt 2\pi\))です。
グラフはこのようになります。
starpolygon3dp_c

gnuplotスクリプトはこちら。

トロコイド(2次元)


トロコイドと呼ばれる曲線があります[2]。
これをgnuplotで書いてみましょう。数式は[2]を参考にして以下の通りです。
\(
\begin{equation}
\left\{
\begin{aligned}
x& = \left[(n-1)\cos t +h\cos((n-1)t)\right]/n \\
y& = \left[(n-1)\sin t +h\sin((n-1)t)\right]/n
\end{aligned}
\right.
\end{equation}
\)
\(h=1\)の時、半径が1の円に内接するように決めています。
また、\(n\)が整数の時、内接する円が外側の円をちょうど一周回った時に元の位置に戻る条件です。
別に整数でなくても構いません。その時はもっと複雑なものになることでしょう。

書いてみますと曲線はこうなります。
自由度\(h\)を1にしてグラフを書いてみましょう。
trocoid2d_3_10_c

自由度hを少し変えてみましょう。
trocoid2dh_3_10_c

トロコイド(3次元)


3次元の場合は多面体の時と同じように、平面のx,yの媒介変数によるトロコイドの関数をそれぞれhcyc(t),hcys(t)と置くと、
\(
\begin{equation}
\left\{
\begin{aligned}
x& = {\rm hcys}(u)\cdot {\rm hcyc}(v) \\
y& = {\rm hcys}(u)\cdot {\rm hcys}(v) \\
z& = {\rm hcyc}(u)
\end{aligned}
\right.
\end{equation}
\)
と書けます。
媒介変数\(u,v\)の範囲は(\(0\le u \lt \pi, \;\; 0\le v \lt 2\pi\))です。

trocoid3d_3_10_c
n=3,4,5,6
n=7,8,9,10の順です。

gnuplotスクリプトはこちら

スポンサーリンク

スピログラフ(2次元)


スピログラフは遊んだ方も多いと思います。これです。
1024px-Spirograph
©Alexei Kouprianov/2007/CC-BY 2.5
スピログラフはトロコイドの特別な時です。スピログラフをもっと一般化したのがトロコイドです[2]。

図示すれば、スピログラフと言うのは
speq_compressed
という二つの円からなる軌道です。黄色の点線の長さが等しい、という束縛条件が課せられます。
数式は上のトロコイドと同じで
\(
\begin{equation}
\left\{
\begin{aligned}
x& = \left[(n-1)\cos t +h\cos((n-1)t)\right]/n \\
y& = \left[(n-1)\sin t +h\sin((n-1)t)\right]/n
\end{aligned}
\right.
\end{equation}
\)
と書けます。

もう少し考えを一般化して、周りを取り囲んでいる形状が円ではない時を考えましょう。その時の数式を考えます。
考え方はトロコイドと一緒ですが、もう少し拡張しましょう。

今、2つの媒介変数による軌道を持っていたとします。1つの媒介変数の軌道上を動かせばスピログラフの考えと同じになります。図で示すと以下のようになります。
spirograph_any_c
スピログラフは両方円であり、滑りが無い(cを決定する条件)場合に対応するわけです。ただ、円である必要性はないので、多角形であろうが、何だろうが数式上では書けるわけです。
興味深い事に、大きな軌道に沿って小さな軌道を動かした、と見ようが小さな軌道に沿って大きな軌道を動かしたとみても数式上では一緒なのです。面白いですね。

いくつか例を挙げます。
五角形上を動かす場合はこうです。
parameter1

数式として,
\(
\begin{equation}
\left\{
\begin{aligned}
x& = f_{1x}(t)+r\cdot f_{2x}(s\cdot t) \\
y& = f_{1y}(t)+r\cdot f_{2y}(s\cdot t)
\end{aligned}
\right.
\end{equation}
\)
と書き表すことにします。これを元にgnuplotのスクリプトを書けば以下のようになります。

色々に変化させた時の色々なときのグラフです。
spr2_any_compressed

rを綺麗な数字にしなければもっと複雑な図が得られます。
また、この考え方は3つの媒介変数の軌道、4つの媒介変数の軌道…として容易に拡張できます。
もっと複雑な模様が欲しければ、もう少し増やしてみましょう。

例えば3つの場合はこうなります。
parameter3_spi
このスクリプトを置いておきます。

この考えを拡張していくと”フーリエ級数の図示化”と言うのができるわけです。

実際にやっている方がいるので紹介しておきますね。

参考文献


[1]Is there an equation to describe regular polygons? -MATHEMATICS
[2]Hypotrochoid -Wolfram Mathworld

アニメーションに便利な関数

アニメーションに便利な関数、手法です。

点の表示


plot sprintf("< echo ''%f %f''", x0,y0)

とすると点\((x_0,y_0)\)が描写されます。

窓関数


窓関数です。関数\(W(x)\)は、
\(
\displaystyle W(x)=\frac{r^{2^n}}{(x-x_c)^{2^n}+r^{2^n}}
\)
書かれます。この関数は\(r\)が窓の横幅を示し、\(n\)が窓の端の様子を決めるパラメータです。窓の広がりはおよそ\(2r\)です。

fwi(n,r,i,ic)=(real(r)**(2**n))/((real(i-ic))**(2**n)+real(r)**(2**n))

加速、減速


extanh
\(
\begin{align}
y(x)&=C_0\tanh(a(x-x_c))+C_1 \\
& C_0 = \frac{f_0-f_1}{t_0-t_1} \\
& C_1 = \frac{-t_1f_0+t_0f_1}{t_0-t_1} \\
& t_0 = \tanh(a(x_0-x_c)) \\
& t_1 = \tanh(a(x_1-x_c)) \\
& x_c = \frac{x_0+x_1}{2}
\end{align}
\)
の関数は点\((x_0,y_0)\)から点\((x_1,y_1)\)に\(\tanh(ax)\)で与えられる関数で書きます。
関数の中心は\((x_c,y_c)=((x_0+x_1)/2,(y_0+y_1)/2)\)になります。
画像の2つの赤い点は\((x_0,y_0)\)と\((x_1,y_1)\)を表しています。
\(a\)は変化の度合いを調節するパラメータです。

この関数は非常に使えます。ラミエルを作っている最中にこの関数を考えましたが、想像以上に役立ちます。

fth(a,x,x0,f0,x1,f1)=(f0-f1)*tanh(a*(real(x)-(x0+x1)*0.5e0))/(tanh(a*(real(x0)-(x0+x1)*0.5e0))-tanh(a*(real(x1)-(x0+x1)*0.5e0)))+(-f0*tanh(a*(real(x1)-(x0+x1)*0.5e0))+f1*tanh(a*(real(x0)-(x0+x1)*0.5e0)))/(tanh(a*(real(x0)-(x0+x1)*0.5e0))-tanh(a*(real(x1)-(x0+x1)*0.5e0)))
 # x0,f0 --> x1,f1

この関数を用いた応用です。
extime_tanh

これはある時間内で高さを反転させるものです。コードはこちら。

set xr[-6:6]
set yr[0.8:2.2]
set size ratio 0.5 1
   
a=1e0
at=0.4e0
x0=-5e0
f0=1e0
x1=5e0
f1=2e0

#set term gif enhanced animate optimize delay 8 size 800,500
#set output 'extime_tanh.gif'

i0=0
i1=20
do for[i=i0:i1]{
    ft0=fth(at,i,i0,f0,i1,f1)
    ft1=fth(at,i,i0,f1,i1,f0)
    plot fth(a,x,x0,ft0,x1,ft1) w l lt 2 lc 3 lw 5 ti sprintf("a=%3.2f, at=%3.2f, (x_0,f_0)=(%3.2f,%3.2f), (x_1,f_1)=(%3.2f,%3.2f)",a,at,x0,f0,x1,f1), sprintf("< echo ''%f %f''", x0,ft0) pt 7 ps 2 lc 7, sprintf("< echo ''%f %f''", x1,ft1) pt 7 ps 2 lc 7

  }

#set out
#set terminal wxt enhanced

三角波、のこぎり波、矩形波、その他の数式

正弦波ではない周期関数、三角波、矩形波等々の数式による表現です。
if文は使っていません。
床関数\(floor(x)\)を主に用いています。

これらが唯一の作り方ではなく、最善の作り方でもありません。

非連続になる関数の場合の特定な関数の場合、中間の値を取るようにしています(フーリエ級数の収束より)。


階段関数

——-
f1
z_f1_x_c
——-
f2
z_f2_x_c
——-
fl
z_fl_x_c


のこぎり波

s1
z_s1_x_c
s2
z_s2_x_c
saw
z_saw_x_c


矩形波

k1,k2,k,ka,kb,kk
z_k1_abx_c

z_k2_abx_c

z_k_abx_c

z_ka_abx_c

z_kb_abx_c

z_kk_abx_c


その他

sl,s,spk
tr,se,de,mo
well1,well2

sl
z_sl_abx_c

s
z_s_ax_c
三角波は、\({\rm acos}(\cos(x))\)とも書けます。

spk
z_spk_abx_c

tr
z_tr_abx_c

se
z_se_abx_c

de
z_de_abx_c

mo
z_mo_abx_c

well1
zwell1_abx_c

well2
z_well2_abx_c


まとめ
periodic_functions_c

全てをまとめたgnuplotのコードは以下のものです。

set size ratio -1
set yr[-2:2]
set xr[-5:5]
set samples 101
set grid
set xtics 1
set ytics 1
set mxtics 2
set mytics 2

f1(x)=floor(x)
f2(x)=-floor(-x)-1e0
fl(x)=0.5e0*(floor(x)-floor(-x)-1e0)

s1(x)=x-floor(x)
s2(x)=x+floor(-x)+1e0
saw(x)=x-0.5e0*(floor(x)-floor(-x)-1e0)

k1(a,b,x)=f1((x+a)/(a+b))-f1(x/(a+b))
k2(a,b,x)=f2((x+a)/(a+b))-f2(x/(a+b))
k(a,b,x)=fl((x+a)/(a+b))-fl(x/(a+b))
kk(a,b,x)=2e0*(k(a,b,x)-0.5e0)

ka(a,b,x)=0.5e0*(sgn(k(a,b,x)-0.25e0))+0.5e0
kb(a,b,x)=0.5e0*(sgn(k(a,b,x)-0.75e0))+0.5e0

sl(a,b,x)=kk(a+b,a+b,x+0.5e0*b+a)*k(a,b,x)

s(a,x)=2e0*abs(s2(x/(a*2))-0.5e0)*kk(a*2e0,a*2e0,x+a)
tr(a,b,x)=k(a,b,x)*s(0.5e0*(a+b),x-0.5e0*b)*(1e0+b/a)+sl(b,a,x-b)

spk(a,b,x)=-abs(kk(a,b,x))+1e0

se(a,b,x)=(x-b-(a+b)*fl(x/(a+b)))/a*k(a,b,x)+0.5e0*(k(a,b,x)*(1e0-b/a)+1e0)*spk(a+b,a+b,x)

de(a,b,x)=-se(a,b,x)*2e0*(k2(a+b,a+b,x-0.5e0*b)-0.5e0)
mo(a,b,x)=de(a*0.5e0,b+a*0.5e0,x+a*0.5e0)+de(a*0.5e0,b+a*0.5e0,-(x+a*0.5e0))

well1(a,b,x)=0.5e0*(sgn((abs(2e0*(x-b)/a)-1e0)+ka(1e0,1e0,abs(2e0*(x-b)/a))-0.5e0))+0.5e0
well2(a,b,x)=0.5e0*(sgn((abs(2e0*(x-b)/a)-1e0)+kb(1e0,1e0,abs(2e0*(x-b)/a))-0.5e0))+0.5e0