相加相乗平均をAxes3Dで可視化[Pythonで数学]

みなさん相加相乗平均は知っていますか?

たぶん数Ⅱくらいの範囲だと思うのでほとんどの人が聞いたことあると思います。

不等式の証明でよく使うやつですね。

a>0,b>0のとき常に

$$\frac{(a+b)}{2} >= \sqrt{ab}$$

っていうべんりなものです。

今回はこれを可視化してみて相加平均と相乗平均を視覚的にみてみようというかんじでやっていきます。

あと普通は相乗平均って言ったらa>0,b>0の場合のみですが、今回はa<0,b<0のときもいけるように、

a<0,b<0のときは

$$-\sqrt{ab}$$

にしてちょっと拡張して今回はやっていくので許してください。

なしてするんですか?

ここで大体の流れを書いておきます。

相加平均も相乗平均も見ての通り2変数関数なのでグラフにしようとすると3次元のグラフが必要になります。

なのでpythonでグラフ描画といえばmatplotlibと思うかもしれませんがmatplotlibだけだと3DのグラフをかけないのでさらにAxes3Dを追加してやっていきます。

こんなかんじでやっていきまーす。

相加相乗平均を可視化

import matplotlib.pyplot as plt
import scipy
from mpl_toolkits.mplot3d import Axes3D
fig=plt.figure()
ax=Axes3D(fig)
ax.set_xlabel("a")#x軸の名前をa、
ax.set_ylabel("b")#y軸の名前をb、
ax.set_zlabel("average")#z軸の名前をaverageにする
hani=15
a=list(range(-1*hani,hani+1))#-15から15までの整数のリストを作る
b=list(range(-1*hani,hani+1))
for i in a:
    for k in b:
        if i*k>0:#a*bが正のとき
            if i>0:#aもbも正のとき
                sojo=scipy.sqrt(i*k)#aとbの相乗平均
                soka=(i+k)/2#aとbの相加平均
                ax.scatter(i,k,sojo,c="r",alpha=0.5)#相乗平均を赤色で散布する
                ax.scatter(i,k,soka,c="b",alpha=0.5)#相加平均を青色で散布する
            else:#aもbも負のとき
                sojo=-1*scipy.sqrt(i*k)
                soka=(i+k)/2
                ax.scatter(i,k,sojo,c="r",alpha=0.5)
                ax.scatter(i,k,soka,c="b",alpha=0.5)
        else:#a*bが負のとき
            soka=(i+k)/2
            ax.scatter(i,k,soka,c="b",alpha=0.5)#相加平均を散布する
ax.scatter(0,0,0,c="r")
plt.show()

上から見ていきまーす。

Axes3Dの使い方

fig=plt.figure()
ax=Axes3D(fig)
ax.set_xlabel("a")#x軸の名前をa、
ax.set_ylabel("b")#y軸の名前をb、
ax.set_zlabel("average")#z軸の名前をaverageにする

axes3dはこうやってつかうらしいです。大体覚えてたほうがいいかもですね。

ここはまあ大丈夫ですね。

インスタンス化してラベルの名前を設定しているだけです。

こんなかんじです。

値の範囲を設定

hani=15
a=list(range(-1*hani,hani+1))#-15から15までの整数のリストを作る
b=list(range(-1*hani,hani+1))

ここも書いてる通りですね。

わざわざhaniに15を入れてる理由は、もし値の範囲を変えたいって思ったときに4か所も変えるのが面倒なのでhaniを変えたら全部一気に変わるようにしています。

わたしは-15~15くらいがちょうどよかったのでこうしてますがもちろん色々変えてやってみてもいいと思います。

相加相乗平均の点を打っていきます

for i in a:
    for k in b:
        if i*k>0:#a*bが正のとき
            if i>0:#aもbも正のとき
                sojo=scipy.sqrt(i*k)#aとbの相乗平均
                soka=(i+k)/2#aとbの相加平均
                ax.scatter(i,k,sojo,c="r",alpha=0.5)#相乗平均を赤色で散布する
                ax.scatter(i,k,soka,c="b",alpha=0.5)#相加平均を青色で散布する
            else:#aもbも負のとき
                sojo=-1*scipy.sqrt(i*k)
                soka=(i+k)/2
                ax.scatter(i,k,sojo,c="r",alpha=0.5)
                ax.scatter(i,k,soka,c="b",alpha=0.5)
        else:#a*bが負のとき
            soka=(i+k)/2
            ax.scatter(i,k,soka,c="b",alpha=0.5)#相加平均を散布する

ここがメインですね。

どういう構成?

二重ループになっています。

まず一重目のループでaのリストの値それぞれにアクセスしてiにいれてます。

そしてそのiのおのおのについてにじゅめのループでbのリストの値それぞれにアクセスしてkにいれています。

文章ではわかりにくいかもしれませんが文章で理解してください。

分からなくても何回か読んでたら分かると思います。

場合分け

if i*b>0:というのがありますね

ここで相乗平均が出せるかどうかを判定しています。

もしi*bが負であったら、相乗平均の式を思い出してもらうとわかるようにルートの中身が負になってしまい実数になりません。

なのでまずここで分けています。

そしてi*b>0となるのはiとkが同符号であったらプラスでもマイナスでもどっちでもいいですよね。

マイナス掛けるマイナスはプラスですよね。

なのでそこをまたifでわけています。

a,bがともに負の時は

$$-\sqrt{ab}$$

を使うので相乗平均のところで-1をかけています。

ax.scatter

ax.scatterの使い方は基本的には

ax.scatter(X,Y,Z)

です。で、さらに色とか透明度とかも指定できます。

今回は色は相乗平均はc=”r”で赤にして相加平均はc=”b”で青にしています。

またグラフを描画してみるとわかるのですが透明度が全くないと赤と青がかぶって下のほうにあるのが見えなくなるので透明度はalpha=0.5で半分くらいにしています。

alphaは0~1で0のほうが透明になっています。デフォルトは1だと思います。

 

表示します

ax.scatter(0,0,0,c="r")
plt.show()

さっきの場合分けでは(0,0,0)がないのでここで打っておきます。

そしてplt.show()すると

できたー。

まさにa>0,b>0のときつねに

$$\frac{(a+b)}{2} >= \sqrt{ab}$$

になっていますよね。青のほうが赤よりつねに上ですね。

相乗平均はaとbの差が大きくなればなるほど相加平均から離れていくのもよくわかります。

できましたー

本当は散布図じゃなくて曲面とかでできるんじゃないかとも思っているんですけどaxes3Dは全然使ったことなくて慣れていないので調べてもよくわかりませんでしたのでできませんでした。

申し訳ないことでございます。

まあきれいにできたからいいですね。

さようなら