はじめに
こちらの本を読みつつ、課題・問題を解いてみます。
「『行列プログラマー』の課題・問題を解いてみる (0章 関数) - Qiita」の続き。「1.4.7 オイラーの公式」の前に一旦上げておきます。
1章 体
1.4 ℂと遊ぼう
課題 1.4.1
まず、上記の複素数から成る集合かリストを変数 S に代入せよ。
点を複素数平面上に表示するには、本書のウェブサイトで提供している plotting モジュールに含まれる plot というプロシージャを用いる。このプロシージャをモジュールから読み込むには以下のようにする。>>> from plotting import plot
S の点を表示するには、次のようにする。
>>> plot(S, 4)
すると Python はブラウザのウィンドウを開き、S で指定された複素平面上の点を表示してくれる。plot の第 1 引数は複素数 (あるいは 2 つの数から成るタプル) の集合で、第 2 引数は表示する図のスケールを指定している。この場合、実部及び虚部の絶対値が 4 以下の複素数が表示される。第 2 引数は省略可能で、デフォルト値は 1 である。もう 1 つの省略可能な引数があり、それは点の大きさを指定するものである。
>>> from plotting import plot
>>> S = {2+2j, 3+2j, 1.75+1j, 2+1j, 2.25+1j, 2.5+1j, 2.75+1j, 3+1j, 3.25+1j}
>>> plot(S, 4)
1.4.1 複素数の絶対値
1.4.2 複素数を足すこと
課題 1.4.3
内包表記を用いて S の各要素に 1 + 2i を足し、新たな図を描け。
>>> plot({1+2j+z for z in S}, 4)
>>> plot({1+2j+z for z in S}, 4)
1.4.3 複素数に正の実数を掛けること
課題 1.4.7
課題 1.4.3 のような内包表記を用いて、S の全ての複素数を半分にした新しい図を描け。
>>> plot({z/2 for z in S}, 4)
1.4.4 複素数に負の実数を掛けること:180 度の回転
1.4.5 i を掛けること:90 度の回転
課題 1.4.8
S の各点を 90 度回転し、更に、半分にスケーリングした図を描け。ただし、内包表記を用いて S の各要素に複素数を 1 つ掛けることで実現すること
>>> plot({z*1j/2 for z in S}, 4)
課題 1.4.9
S の各店を 90 度回転し、更に半分にスケーリングした後で、下に 1 目盛、右に 2 目盛ずらした図を描け。ただし、内包表記を用いて、S の各要素に複素数を掛け、また、複素数を足すことで実現すること
>>> plot({z*1j/2+2-1j for z in S}, 4)
課題 1.4.10
本書のウェブサイトで提供している image モジュールには file2image(filenae) プロシージャが含まれ、これは png 形式の画像を読み込むためのものである。このプロシージャの引数に、画像ファイルの名前を指定して実行し、戻り値を変数 data に代入せよ。サンプルのグレースケール画像 img01.png が本書のウェブサイトからダウンロードできる。
data の値はリストのリスト (リストを要素とするリスト) になっており、data[y][x] は、(x, y) に位置するピクセルの明るさの強度を表している。(0, 0) は画像の左上のピクセル、(width-1, height-1) は画像の右下のピクセルである。強度は 0 から 255 の整数で表され、0 が黒、255 が白である。
内包表記を用いて、画像中の強度が 120 未満のピクセルの場所 (x, y) を表現する複素数 x + iy kあら成るリスト pts を定義し、図示せよ。
>>> from image import file2image
>>> data = file2image('img01.png')
>>> pts = [x - y * 1j + len(data) * 1j for y in range(len(data)) for x in range(len(data[y])) if data[y][x][0] < 120]
>>> plot(pts, 190)
課題 1.4.11
S が表す画像を原点にずらすようなプロシージャ f(z) を書け。内包表記を用いてこのプロシージャを S に適用し、結果を図示せよ。
def f(z):
x_list = [v.real for v in z]
y_list = [v.imag for v in z]
x_center = (min(x_list) + max(x_list)) / 2
y_center = (min(y_list) + max(y_list)) / 2
return [v - x_center - y_center * 1j for v in z]
>>> from util import f
>>> lot(f(list(S)), 4)
課題 1.4.12
S の代わりに pts を用いて課題 1.4.8 を繰り返せ。
>>> plot([p*1j/2 for p in pts], 190)