第3回:▼ 連続な曲線を描く
■ Jupyter notebook によるテキストの入力
Markdownセルと Markdown 記法
Jupyter notebook のセルには,複数の種類(Cell type)がある.
既定のセルの Cell type は,Code
である. プログラム片を入力して,SHIFT
キーと ENTER
キーを同時に押して実行すると, 出力セルに実行結果が表示される.
Cell type を Markdown に変更すると, Markdown 記式によるテキストを入力できる.
Markdown 記式でテキストを入力し, SHIFT+ENTERを押して実行すると, Markdown記式で整形された文書が表示される.
Markdown記法では,段落の区切りは空行である. 空行をはさまない行替えは,前の行に続けて,同じ段落に配置される.
文字列の飾り記法は省略する(たくさん使用しない方がよい).
URLリンク
URLリンクを書くには,次のように記述する.→ [
表示名 ](
URL )
例
[Julia 1.9 Documentation](https://docs.julialang.org/en/v1.10/)
数式
Markdown記法では,数式を挿入することができる. ダラー記号 $
1つで囲まれた数式は行内数式(inline math), ダラー記号 $
2つで囲まれた数式は別行立て数式(display math)である. 数式そのものは LaTeX 記法で記述する. いくつか例を示す.
- 数式内の文字は変数とみなされ,斜体で表される.
$x+1$
→ $x+1$ - 上付き
$x^{2}$
→ $x^{2}$ - 下付き
$x_{3}$
→ $x_{3}$ - 分数
$\dfrac{a}{b}$
→ $\dfrac{a}{b}$ - 関数
$f(x) = x^{2}+1$
→ $f(x) = x^{2}+1$ - 三角関数
$\sin{x}, \tan{x}$
→ $\sin{x}, \tan{x}$ - 指数対数関数
$\exp{x}, \log{x}$
→ $\exp{x}, \log{x}$ - テキスト内の直立体(roman style)
$a\;\mathrm{over}\;b$
→ $a\;\mathrm{over}\;b$ - 総和
$\sum_{i=0}^{m}i$
→ $\sum_{i=0}^{m}i$ - 総和を「行立て」する
$$\sum_{i=0}^{m}i$$
→
\[\sum_{i=0}^{m}i\]
- 積分
$\int_{0}^{1}x dx$
→ $\int_{0}^{1}x dx$ - 積分を「行立て」する
$$\int_{0}^{1}x dx$$
→
\[\int_{0}^{1} x dx\]
- カッコのペア
$\left( \dfrac{1}{2} \right)$
→
\[\left( \dfrac{1}{2} \right)\]
$\left\{\left( \dfrac{1}{2} \right)\right\}$
→
\[\left\{\left( \dfrac{1}{2} \right)\right\}\]
$\left[\left\{\left( \dfrac{1}{2} \right)\right\}\right]$
→
\[\left[\left\{\left( \dfrac{1}{2} \right)\right\}\right]\]
▼ 鉛直上投げ自由落下運動を描く
(力学の問題)
鉛直上向きに投げられた球が,重力のみを感じて自由落下するとする. 時刻 $t=0$において,高さ $y=0$, 鉛直上向きの速度 $v_0$ とすると, 時刻 $t$における,高さ $y$と 鉛直上向きの速度 $v$ は,以下のように表される.
\[\begin{aligned} v & = v_0 - gt, \\ y & = v_0 t - \dfrac{1}{2}gt^2 \end{aligned}\]
各時刻の速度を描く. 長さの単位としてメートル m
, 時間の単位として秒 s
を(組立て単位を含めて)一貫して用いる.
重力加速度 $g = 9.8\;\mathrm{m/s^2}$
初速度を $v_0 = 10\;\mathrm{m/s}$ としよう.
各時刻における速度を描く.
using Plots
#gr() #pythonplot()
plot(framestyle=:axes)
v0 = 10 # m/s
g = 9.8 # m/s^2
ts = 0:0.1:3 # s
vs = v0 .- g * ts
plot!(ts, vs, lc=:blue, xlabel="time / s", ylabel="v / m s^-1")
各時刻における高さを描く.
# 続けて
ys = v0 * ts .- g * ts .^ 2 / 2
plot(ts, ys, lc=:red, xlabel="time / s", ylabel="y / m")
この後の章の ▲ 鉛直上投げ自由落下運動を描く・上下2枚のサブプロット では, 速度-時刻,高さ-時刻の二つのプロットを一つの画像にまとめる.さらに, ▲ 鉛直上投げ自由落下運動を描く・ダブルYプロット では,時刻を共通としたダブルYグラフを作成する.
▲ 練習:鉛直上投げ自由落下運動
初速度 v0
を増減して描いてみよ.
▲ 練習:斜めに飛ばした球の軌跡
(力学の問題)
鉛直上向きに対して 角度 $b$をつけて投げた球が,重力のみを感じて運動するとき,その球の軌跡を描け.
最初は $b = 15^{\circ}$として描け.
次に,初速度$v0$を変えた場合を,1つのプロットに示せ. また,角度$b$を変えた場合を,1つのプロットに示せ.
▼ 定義域・値域
関数 $y=f(x)$ の定義域(domain)とは, 独立変数(independent variable)$x$ の取りうる値からなる集合である. ちなみに,従属変数(dependent variable) $y$ が取りうる値からなる集合を,値域(range)という
本章では, 定義域が実数全体,あるいは,正の数の集合である関数について, プロットを描いてみる.
▶ 定数 pi
定数 pi
は円周率である.
julia> pi
π = 3.1415926535897...
プロット既定値
using Plots
#gr() #pythonplot()
Plots.reset_defaults()
default(
size=(720,480), # <= 全体の寸法を大きくする
lims=:auto, aspect_ratio=:auto,
label="",
xlabel="x", ylabel="y")
▼ 正弦関数・余弦関数を描く
関数 | 数式 | ラジアン単位 | 角度単位 | $pi$単位 |
---|---|---|---|---|
正弦 | $\sin{x}$ | sin(x) | sind(x) | sinpi(x) |
余弦 | $\cos{x}$ | cos(x) | cosd(x) | cospi(x) |
ラジアン単位
引数がラジアン単位の正弦,余弦 sin
, cos
julia> sin(pi / 6)
0.49999999999999994
julia> cos(pi / 6)
0.8660254037844387
cos.()
や sin.()
のように,関数名の直後にピリオド .
を入れると, ベクトルや範囲を引数にとり,計算結果をベクトルで返す.
julia> xs = [pi / 4, pi / 6, pi / 2];
julia> sin.(xs)
3-element Vector{Float64}: 0.7071067811865475 0.49999999999999994 1.0
julia> cos.(xs)
3-element Vector{Float64}: 0.7071067811865476 0.8660254037844387 6.123233995736766e-17
範囲型の引数を与えて,プロットを描く.
using Plots
#gr() #pythonplot()
xs = -2pi:pi/360:2pi
plot(xlabel="radian", ylims=(-1.2,1.2))
plot!(xs, cos.(xs), label = "cos")
plot!(xs, sin.(xs), label = "sin")
vline!([0], lc=:black, lw=0.5)
円周率単位
引数が円周率単位の正弦,余弦 sinpi
, cospi
using Plots
#gr() #pythonplot()
xs = -2:1/360:2
plot(xlabel="pi", ylims=(-1.2,1.2))
plot!(xs, cospi.(xs), label = "cospi")
plot!(xs, sinpi.(xs), label = "sinpi")
vline!([0], lc=:black, lw=0.5)
角度単位
引数が角度単位の正弦,余弦 sind
, cosd
using Plots
#gr() #pythonplot()
plot(
xlabel="degree", ylims=(-1.2,1.2))
xs = -360:1:360
plot!(xs, cosd.(xs), label = "cosd")
plot!(xs, sind.(xs), label = "sind")
plot!(xticks=-360:90:360) # <= 横軸目盛の設定
vline!([0], lc=:black, lw=0.5)
ラジアンと角度との相互変換
julia> # rad2deg rad2deg(pi / 4)
45.0
julia> rad2deg(pi / 2)
90.0
julia> rad2deg(pi)
180.0
julia> rad2deg(-pi / 4) # deg2rad
-45.0
julia> deg2rad(45)
0.7853981633974483
julia> deg2rad(90)
1.5707963267948966
julia> deg2rad(180)
3.141592653589793
julia> deg2rad(-45)
-0.7853981633974483
▼ 楕円を描く
楕円を陰関数で表示すると
\[\left(\dfrac{x}{a}\right)^2+\left(\dfrac{y}{b}\right)^2 = 1\]
楕円を媒介変数表示(パラメータ曲線)すると
\[\begin{aligned} x & = a \cos \theta \\ y & = b \sin \theta \end{aligned}\]
媒介変数表示を用いて,楕円上の各点の座標を計算する.
アスペクト比を等しくして,正しい図形を表示しよう.
using Plots
#gr() #pythonplot()
plot(aspect_ratio=:equal, legend=false)
ts = 0:pi/18:2pi
xs = cos.(ts)
ys = sin.(ts)
plot!(xs, ys, label="circle")
xs2 = 2 * cos.(ts)
plot!(xs2, ys, label="ellipse")
▼ アルキメデスの渦を描く
平面座標上の点 $(x,y)$は, 極座標 $(r, \theta)$ を用いても表示できる. 平面座標 $(x, y)$と極座標 $(r, \theta)$ との対応は
\[\begin{aligned} x & = r \cos \theta, \\ y & = r \sin \theta \end{aligned}\]
である.
次の関係で結ばれた曲線を,アルキメデスの渦という.
\[r = \theta\]
これを描いてみよう.
using Plots
#gr() #pythonplot()
plot(aspect_ratio=:equal, legend=false)
ts = 0:pi/180:2pi
xs = ts .* cos.(ts)
ys = ts .* sin.(ts)
plot!(xs,ys)
▲ 練習
上では $\theta \ge 0$ の範囲で,曲線を描いた. パラメータ $\theta < 0$ の範囲まで含めたら, どのような曲線になるか,予測せよ. プログラムを書き実行し,確かめてみよ. 予測と合っていたか?
▼ 花曲線を描く
整数 $n$ に対して,以下の式で表される曲線を,花曲線(flower curve)という.
\[r = \cos(n \theta)\]
次のプログラムは,$n = 3$ の花曲線を描く.
using Plots
#gr() #pythonplot()
plot(aspect_ratio=:equal, legend=false)
n = 3
ts = 0:pi/180:2pi
rs = cos.(n * ts)
xs = rs .* cos.(ts)
ys = rs .* sin.(ts)
plot!(xs, ys)
整数 $n$ を変えると,色々な花曲線が得られる.
▲ 練習
上の式の代わりに
\[r = \sin(n \theta)\]
としたら,どのような曲線になるか? 予想した上で,プログラムを書き実行し,確かめてみよ. 予想と一致していたか?
▼ 指数関数を描く
底 | 数式 | Julia |
---|---|---|
$a > 0$ | $a^{x}$ | a^x |
$2$ | $2^{x}$ | exp2(x) |
$e$ | $e^{x}$, $\exp{x}$ | exp(x) |
$10$ | $10^{x}$ | exp10(x) |
正の数 $a > 0$ を底(exponent)とする指数関数(exponential function)
\[y = a^x\]
底 $a = 2$ の場合.
using Plots
#gr() #pythonplot()
plot(legend=false)
xs = -3:0.01:3
plot!(xs, 2.0 .^ xs)
底を $2, 3, 4. 5$ と増やす.$x > 0$ の範囲のみ描く.
using Plots
#gr() #pythonplot()
plot(xlims=(0,3))
xs = -3:0.01:3
plot!(xs, 2.0 .^ xs, label = "a=" * string(2))
plot!(xs, 3.0 .^ xs, label = "a=" * string(3))
plot!(xs, 4.0 .^ xs, label = "a=" * string(4))
plot!(xs, 5.0 .^ xs, label = "a=" * string(5))
plot!(xs, 6.0 .^ xs, label = "a=" * string(6))
▲ 練習:指数関数:繰り返しで底を変える
上のプログラムを,for
文を用いた繰り返しとして書き直してみよ. すなわち,plt.plot()
文を1つにしてみよ.
参考→ ■ for
文
▶ 自然対数の底
定数 ℯ
は,自然対数の底である.
julia> ℯ
ℯ = 2.7182818284590...
ℯ
は e
とは異なる文字である. 「ℯ」は,バックスラッシュ \ に続けて euler と入力してから,TABキーを押すことによって入力できる.
定数 Base.MathConstants.e
も,自然対数の底である.
julia> Base.MathConstants.e
ℯ = 2.7182818284590...
▶ 軸のスケールを変える
$x$ 軸,$y$ 軸のスケールを指定するには, キーワード引数 xscale
, yscale
を用いる. 何も指定しない場合(既定値)は,線形 :linear
である. 引数に :log
を指定すると,$10$ の対数で,その軸を描く.
$y$ 軸だけ対数スケール yscale=:log10
に指定したプロットが,よく見る片対数プロットである.
using Plots
#gr() #pythonplot()
plot(yscale=:log10) # <=
xs = -4:0.01:4
for a in [2.0, ℯ, 3.0, 4.0, 5.0, 6.0]
plot!(xs, a .^ xs, label = "a=" * string(a))
end
xlims!(-1, 3)
ylims!(1e-1, 1e3)
すべての底について,指数関数が $a^{0} = 1 = 10^{0}$ で交わることを観察するために補助線を引こう.
以下の文を追加する.
# 上に続けて
vline!([0], color = :black, lw = 0.5)
hline!([1], color = :black, lw = 0.5)
▶ 関数 exp, exp2, exp10
底 $2, e, 10$ については,exp
で始まる関数が定義されている.
exp2
: 底が $2$ の指数関数exp
: 自然対数(底は,自然対数の底 $e$ )exp10
: 底が $10$ の指数関数
using Plots
#gr() #pythonplot()
plot(yscale=:log10)
xs = -4:0.01:4
plot!(xs, exp2.(xs), label = "exp2")
plot!(xs, exp.(xs), label = "exp")
plot!(xs, exp10.(xs), label = "exp10")
xlims!(-1, 3)
ylims!(1e-1, 1e3)
vline!([0], color = :black, lw = 0.5)
hline!([1], color = :black, lw = 0.5)
関数も名前であり,名前をつけること(=変数に代入すること)ができる. 関数のリストを作って for
文で繰り返してみよう. 関数名を string
関数に与えると,関数名の文字列を返す.
using Plots
#gr() #pythonplot()
plot(yscale=:log10)
xs = -4:0.01:4
for f in [exp2, exp, exp10]
plot!(xs, f.(xs), label = string(f))
end
xlims!(-1, 3)
ylims!(1e-1, 1e3)
vline!([0], color = :black, lw = 0.5)
hline!([1], color = :black, lw = 0.5)
▼ 冪乗根を描く
冪 | 数式 | Julia |
---|---|---|
$2$ | $\sqrt{x}$ | sqrt(x) |
$3$ | $\sqrt[3]{x}$ | cbrt(x) |
$n > 0$ | $\sqrt[n]{x}$, $x^{\frac{1}{n}}$ | x^(1/n) |
▼ 平方根を描く
二乗すると $x$ になる数を,$x$ の平方根(square root of $x$ )という. 関数 sqrt(x)
は x
の平方根を求める関数である.
julia> sqrt(0)
0.0
julia> sqrt(2)
1.4142135623730951
julia> sqrt(3)
1.7320508075688772
平方と平方根を同じプロットに描いてみよう. 直線 $y=x$ に対して,鏡の関係になっている.
using Plots
#gr() #pythonplot()
plot(aspect_ratio=:equal)
xs = 0:0.01:3
plot!(xs, xs .^ 2, label = "square")
plot!(xs, sqrt.(xs), label = "square root")
plot!(xs, xs, lc=:black, lw = 0.5, label = "y=x")
xlims!(-0.2, 2.2)
ylims!(-0.2, 2.2)
vline!([1], lc = :black, lw = 0.5)
hline!([1], lc = :black, lw = 0.5)
負の数 $x < 0$ を関数 sqrt
の引数(ひきすう)に与えると,例外(exception)が発生する.が,複素数を引数として与えると,複素数として計算できる(複素数は,もっと後の回で説明する).→ ▶ 負の数に対する平方根
julia> sqrt(-1) # DomainError
ERROR: DomainError with -1.0: sqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
julia> sqrt(complex(-1)) # 複素数を引数に与える
0.0 + 1.0im
▼ 立方根を描く
三乗すると $x$ になる数を,$x$ の立方根(cube root of $x$ )という. 関数 cbrt(x)
は x
の立方根を求める関数である.
立方と立方根を同じプロットに描いてみよう. 直線 $y=x$ に対して,鏡の関係になっている.
using Plots
#gr() #pythonplot()
plot(aspect_ratio=:equal)
xs = 0:0.01:3
plot!(xs, xs .^ 3, label = "cubic")
plot!(xs, cbrt.(xs), label = "cube root")
plot!(xs, xs, lc=:black, lw = 0.5, label = "y=x")
xlims!(-0.2, 2.2)
ylims!(-0.2, 2.2)
vline!([1], color = :black, lw = 0.5)
hline!([1], color = :black, lw = 0.5)
平方と平方根,立方と立方根を,同じプロットに描こう. 点 $(1,1)$ で,曲線が交差している.
using Plots
#gr() #pythonplot()
plot(aspect_ratio=:equal)
xs = 0:0.01:3
plot!(xs, xs .^ 2, label = "square")
plot!(xs, sqrt.(xs), label = "square root")
plot!(xs, xs .^ 3, label = "cube")
plot!(xs, cbrt.(xs), label = "cube root")
plot!(xs, xs, lc=:black, lw = 0.5, label = "y=x")
xlims!(-0.2, 2.2)
ylims!(-0.2, 2.2)
vline!([1], lc=:black, lw = 0.5)
hline!([1], lc=:black, lw = 0.5)
▼ 一般の冪乗根を描く
一般に,正数 $x > 0$ と $2$ 以上の整数 $n$ に対して,$y^n = x$ の解, すなわち,$y = \sqrt[n]{x} = x^{\dfrac{1}{n}}$ を,$x$ の $n$ 乗根(root of $n$-th power, $n$-th root)という.$n$ を指定せずに,冪乗根(べきじょうこん)あるいは冪根(べきこん)と総称する. 「冪」の代わりに「巾」の略字を当てることもある.
using Plots
#gr() #pythonplot()
plot(
legend=:topleft,
aspect_ratio=:equal)
xs = 0:0.01:3
plot!(xs, xs .^ (1 / 2), label = "n=2")
plot!(xs, xs .^ (1 / 3), label = "n=3")
plot!(xs, xs .^ (1 / 4), label = "n=4")
plot!(xs, xs .^ (1 / 5), label = "n=5")
xlims!(-0.2, 2.2)
ylims!(-0.2, 2.2)
hline!([1], color = :black, lw = 0.5)
vline!([1], color = :black, lw = 0.5)
指数 $n$ で繰り返してみる.縦軸・横軸とも対数表示にする.
using Plots
#gr() #pythonplot()
plot(
legend=:topleft,
xscale=:log10, yscale=:log10)
xs = 0:0.01:10
for n = 2:5
plot!(xs, xs .^ (1 / n),
label = "y=x^(1/" * string(n) * ")")
end
xlims!(0.1, 10.0)
ylims!(0.1, 10.0)
hline!([1], color = :black, lw = 0.5)
vline!([1], color = :black, lw = 0.5)
▼ 対数関数を描く
底 | 数式 | Julia |
---|---|---|
a > 0 | $\log_{a}{x}$ | log(a,x) |
$2$ | $\log_{2}{x}$ | log2(x) |
$e$ | $\log{x}$, $\ln{x}$ | log(x) |
$10$ | $\log_{10}{x}$ | log10(x) |
▼ 自然対数
正の数 $x>0$ に対して,$x=e^y$ を満たす数 $y$ を,$x$ の自然対数(natural logarithm of $x$,Napierian logarithm,あるいは単に,logarithm)といい,$\log{x}$ と書く.
関数 log(x)
は,自然対数を求める関数である.
julia> log(1)
0.0
julia> log(ℯ)
1
julia> log(ℯ^2)
2.0
指数関数を,まず線形なプロットで描く.
using Plots
#gr() #pythonplot()
plot()
xs = 0.1:0.01:100
plot!(xs, log.(xs))
今度は,片対数プロットで描く. $x$ 軸を対数で表示すると,直線で表示される.
# 続けて
plot!(xscale=:log10)
plot!(xs, log.(xs))
数学と同様,負の数に対する対数関数は定義されていない.引数に負数を与えると例外が起こる.
julia> log(-1) # DomainError
ERROR: DomainError with -1.0:
数学では $\log$関数を複素数の引数に拡張できる(複素関数論で習う).
結果は,$\log(-1) = i(1+2n)\pi$ ($n$ は整数)である. Juliaでも,複素数の -1
を引数として与えると,$n=0$に対応する値が得られる.
julia> log(complex(-1)) # 複素数を引数に与える
0.0 + 3.141592653589793im
▼ 対数関数
正の数 $a > 0$ に対して,$x=a^y$ を満たす数 $y$ を, 底 $a$ に対する $x$ の対数(logarithm of $a$ to base b; base $a$ logarithm of $x$ )といい,$\log_{a}{y}$ と書く.
関数 log(a,y)
のように,引数(ひきすう)2つを与えると, 底 $a$ に対する $x$ の対数が得られる.
片対数プロットを描く.$\log_{a}{1}=0$ で曲線が交差する.
using Plots
#gr() #pythonplot()
plot(
legend=:topleft,
xscale=:log10)
xs = 0.1:0.01:100
plot!(xs, log.(2, xs), label = string(2))
plot!(xs, log.(xs), label = string(ℯ))
plot!(xs, log.(3, xs), label = string(3))
plot!(xs, log.(10, xs), label = string(10))
hline!([0], color = :black, lw = 0.5)
vline!([1], color = :black, lw = 0.5)
底を for
文で変えてみる.
using Plots
#gr() #pythonplot()
plot(
legend=:topleft,
xscale=:log10)
xs = 0.1:0.01:100
for a in [2, ℯ, 3, 10]
plot!(xs, log.(a, xs), label = string(a))
end
hline!([0], color = :black, lw = 0.5)
vline!([1], color = :black, lw = 0.5)
底 $2$ と $10$ に対しては,それぞれ関数 log2
と log10
が用意されている.
using Plots
#gr() #pythonplot()
plot(
legend=:topleft,
xscale=:log10)
xs = 0.1:0.01:100
plot!(xs, log2.(xs), label = "log2")
plot!(xs, log.(xs), label = "log")
plot!(xs, log10.(xs), label = "log10")
hline!([0], color = :black, lw = 0.5)
vline!([1], color = :black, lw = 0.5)
関数名で繰り返してみる.
using Plots
#gr() #pythonplot()
plot(
legend=:topleft,
xscale=:log10)
xs = 0.1:0.01:100
for f in [log2, log, log10]
plot!(xs, f.(xs), label = string(f))
end
hline!([0], color = :black, lw = 0.5)
vline!([1], color = :black, lw = 0.5)
▲ 練習:色々な連続曲線を描く
ここまで紹介した関数を使って,色々な連続曲線を描いてみよ. Jupyter notebookの Markdown セルを用いて,説明文も加えよ.
★ 今回のまとめ
- Jupyter Notebookを用いたテキスト入力(Markdownセル)
- 実数全域で定義された関数
- 正弦・余弦関数
- 楕円
- 極座標で著された曲線
- アルキメデスの渦
- 花曲線
- 指数関数
- 正数を定義域とする関数
- 平方根・立方根・冪乗根
- 対数関数
- ダブルYプロット
- ダブルYプロットの作成
- ダブルYプロットに共通な凡例の作成
- 描画領域の分割