2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめてのアドベントカレンダーAdvent Calendar 2023

Day 9

楕円曲線をsympyのplot_implicitでグラフにする(その1)

Posted at

暗号理論でも名前だけは聞く楕円曲線ですがこれをグラフに描けと言われても結構難しいですね。sympyのplot_implicitを使えば簡単にグラフにでき、さらにそのグラフをmatplotlibの中に取り込んで利用する方法を紹介します。

sympyのplot_implicitでグラフを描く

例題1: 楕円曲線$y^2=x^3-4x$のグラフを描け

plot_implicitは非常に便利で、関数を$f(x,y)=0$の形(陰関数 implicit function)で与えるとグラフを描いてくれるというものです。

例題では、楕円曲線$y^2=x^3-4x$の式を渡すだけで描いてくれます。

from sympy import var
from sympy.plotting import plot_implicit
import matplotlib.pyplot as plt
var('x,y')
size = 5
plt = plot_implicit(x**3-4*x-y**2, (x, -size, size), (y, -size, size))

image.png

楕円曲線のグラフとその上の点を表示

ただこれだと他のmatplotlibの機能と組み合わせて他の図形を重ね合したりすることが出来ません。そこでplot_implicitを使うけど描画せずにget_pointsで座標だけを取得してmatplotlibのfillを使って描きます。
この座標だけを取得する関数plot_fxyを以下のように定義します。

import sympy as sp
def plot_fxy(G,CX,CY):
  p = sp.plot_implicit(G, (x,)+CX, (y,)+CY, show=False)[0].get_points()[0]
  px, py = [], []
  for (ix, iy) in p:
    px.extend([ix.start, ix.start, ix.end, ix.end, None])
    py.extend([iy.start, iy.end, iy.end, iy.start, None])
  return (px, py)

これを使って次の例題を解きます

例題2: 楕円曲線$y^2=x^3+17$のグラフを描き次の5点(-2,3), (-1,4), (2,5),(4,9),(8,23)がこの曲線上にあることを確認せよ

ここではX, Y=[-30,30]のサイズのキャンバスがinit_subplot(コードは最後に添付)で定義されたとして以下のコードで描くことができます。

# 楕円曲線とその上の点
import matplotlib.pyplot as plt
sizex = 30
CX, CY = (-sizex, sizex), (-sizex, sizex)
ax = init_subplot(plt, CX, CY)

x, y = sp.symbols("x y")
ax.fill(*plot_fxy(x**3+17-y**2, CX, CY), facecolor='blue')
QP = [(-2,3),(-1,4),(2,5),(4,9),(8,23)]
for (qx,qy) in QP:
  ax.plot(qx,qy, marker='o', ms="2.0", color='red')
  ax.text(qx+1,qy-1, f"({qx},{qy})")
plt.show

image.png

色々な楕円曲線を描く

次は楕円曲線(Wikipedia)にある楕円曲線のカタログのようにヴァイエルシュトラスの標準形のaとbを変えたグラフを描いてみます。

# 楕円曲線のカタログ
sizex = 3
CX, CY = (-sizex, sizex), (-sizex, sizex)
am, bm = 4, 4
ax = init_subplot(plt, CX, CY, am, bm)  # Create 4 x 4 subplot

x, y = sp.symbols("x y")
for c in range(am):
  for r in range(bm):
    a, b = r-2, c-1
    ax[r,c].fill(*plot_fxy(x**3+a*x+b-y**2, CX, CY), facecolor='blue')
    ax[r,c].set_title(f"** a={a}, b={b} **")
plt.show

image.png

これで楕円曲線をmatplotlibのsubplot上に描けるようになったので、次の(その2)楕円曲線の演算をグラフで表していきたいと思います。

(開発環境:Google Colab)

(添付)init_subplotのソースコード

def init_subplot(plt, cx, cy, nccol=1, ncrow=1):
  if nccol*ncrow == 1:
    fig, ax = plt.subplots(nccol, ncrow, figsize=(4,4))
    plt.tick_params(labelsize="large")
    ax.set_xlim(cx); ax.set_ylim(cy)
    ax.set_aspect('equal')
    ax.grid()
  else:
    fig, ax = plt.subplots(nccol, ncrow, figsize=(8,8))
    plt.tick_params(labelsize="small")
    plt.rcParams["font.size"] = 5
    plt.tight_layout()
    for c in range(nccol):
      for r in range(ncrow):
        ax[r,c].set_xlim(cx); ax[r,c].set_ylim(cy)
        ax[r,c].set_aspect('equal')
  return ax

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?