『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

符号関数

符号関数(sign function)

符号関数は変数 $x$ の符号に応じて、$-1,\ 0,\ 1$ のいずれかの値を返す関数として定義され、$\mathrm{sgn}(x),\ \mathrm{Sgn}\,x,\ \mathrm{sign}\,x$ などの記号で表されます。
 \[\mathrm{sgn}x=\left\{\begin{matrix}1\quad (x \gt 0)\\0\quad (x=0)\\-1\quad (x \lt 0)\end{matrix}\right.\]
符号関数をグラフに表すと次のようになります。
 
Python 符号関数sgn(x), sign(x)のグラフ
このグラフを描くコードは記事の後半に載せてあります。sgn は英語の sign の略ですが、正弦関数のサインと紛らわしいので、ラテン語の signum を使ってシグナム関数 (signam function) とよばれることもあります。

符号関数はヘヴィサイドの階段関数 $\mathrm{H}_c(x)$ と
 \[\mathrm{sgn}(x)=2\mathrm{H}_{1/2}(x)-1\]
という関係で結びついています。また、符号関数を微分するとデルタ関数となることが知られています。
 \[\frac{d}{dx}\mathrm{sgn}x=2\delta(x)\]
グラフからも明らかなように、上式は符号関数が原点で傾きが無限大となることを意味しています。原点以外の傾きは $0$ です。

複素変数の符号関数

符号関数は
 \[\mathrm{sgn}x=\left\{\begin{matrix}\cfrac{x}{|x|}\quad (x \neq 0)\\0\quad (x=0)\\\end{matrix}\right.\]
と表すこともできます。複素変数 $z=x+iy$ の符号関数は、これをそのまま拡張して
 \[\mathrm{sgn}z=\left\{\begin{matrix}\cfrac{z}{|z|}\quad (z \neq 0)\\0\quad (z=0)\\\end{matrix}\right.\]
と定義します。たとえば $z=2+i$ のとき、符号関数の値は
 \[\mathrm{sgn}(2+i)=\frac{2+i}{\sqrt{5}}\]
というように、絶対値 $1$ の複素数へと変換されます。すなわち、$w=\mathrm{sgn}(z)$ とおくと、$z$ 平面上の点は符号関数によって $w$ 平面の単位円に移されることになります。

numpy.sign()

NumPy には符号関数 numpy.sign() が実装されています。

# NUMPY_SIGN

# In[1]

import numpy as np

x = np.array([0, 10, -10])

print(np.sign(x))
# [0 1 -1]

numpy.sign() を使って冒頭に掲載した符号関数のグラフを描いてみましょう。

# In[2]

import matplotlib.pyplot as plt

# フィギュアを設定
fig = plt.figure()

# グラフ描画領域を追加
ax = fig.add_subplot(111)

# グリッド線を表示
ax.grid(linestyle = "--")

# グラフタイトルを設定
ax.set_title("Sign Function", fontsize = 16)

# x軸とy軸のラベルを設定
ax.set_xlabel("x", fontsize = 16)
ax.set_ylabel("y", fontsize = 16)

# 区間[-5,5]を64分割
x = np.linspace(-5, 5, 65)

# データxの各要素について符合関数y=sgn(x)を計算
y = np.sign(x)

# 符号関数のグラフをプロット
ax.plot(x, y, color = "darkblue")

Python 符号関数sgn(x), sign(x)のグラフ

コメント

  1. あとりえこばと より:

    【AI連載小説】科学とコードの交差点(39)「符号関数の実装」
     
    開誠と明信は、図書館の一角で符号関数(符号関数)についての実装について議論していた。開誠がコンピュータを操作し、Jupyter Notebookを立ち上げると、明信は興奮気味に尋ねました。
    「開誠、符号関数の実装って、いくつか方法があるよね。どんなアプローチをとるか決めた?」
    「そうだな、まずは数学的な定義から出発して、Pythonでの実装に移ろうか」
    開誠はノートパソコンのキーボードを叩きながら、数学的な定義に基づくシンプルな実装を示しました。

    def sign_function(x):
        if x > 0:
            return 1
        elif x < 0:
            return -1
        else:
            return 0

    「確かにこれはシンプルだけど、ゼロに対する挙動が微妙だよね」
    「そうだな、ゼロに対する挙動は様々な定義がある。ゼロで0を返すのが一般的だけど、別の定義もある」
    「そうだね。他にどんな方法があるか考えてみよう」
    「もう一つの方法として、numpyライブラリのsign関数を使う方法がある。これはゼロに対する挙動も調整できる」

    import numpy as np
    
    def sign_function_np(x):
        return np.sign(x)

    「これは便利だね。でも、もっと数学的な表現で実装することもできるんじゃないか?」
    「確かに、数学的な表現もある。数学的な定義をベースにして、次のようにも書ける」

    def sign_function_math(x):
        return (x > 0) - (x < 0)

    開誠と明信は、それぞれの実装について議論を深め、どの方法が特定の状況において適しているかについて話し合っていった。