割り算アルゴリズム その2

割り算アルゴリズムその2

  • 単項式を消していく事で,割り算を実現
  • 多項式の割り算は,単項式を少しずつ消していく
  • (順序が重要)

——–

はじめに?

「割り算アルゴリズム」で一記事にしようとしていましたが,長くなってしまったので分割しました.この記事では,多項式の割り算を扱っていきます.

理論

準備(前提知識)

  • 単項式,多項式
  • 係数
  • 順序
  • 簡単な割り算アルゴリズム(前記事)

目標(理論)

最終的には,多項式と多項式で割り算をすることが目標です.

複雑な例への準備

もし,余りrをさらに割ることができるならば,割り算アルゴリズムはどうなるか考えます.
これは,例えば式 F = xyz を, F1 = xy + yz F2 = xyz + xy で割るときに重要となります.もしF1で割り切ってしまって,さらにF2で割れるなら,F2でも割る必要があります.

これを式にして表現してみます.

y = q1 \times x1 + r1

r1 = q2 \times x2 + r2

r2 = q3 \times x3 + r3

\vdots

  • y は,割られる式です.
  • q1,q2,\cdots は,商です.
  • x1,x2,\cdots は,割る式です.
  • r1,r2,\cdots は,余りです.

上の式では,1行目で計算した余りr1 がさらに割れるとします.
なので,余りをさらに割ります.また余りが割れるなら・・・という計算です.

とても簡単な例で同じ計算をしてみます.
y = 103,2 で割る事を考えます.

10 = 3 + 7
7 = 3 + 4
4 = 2 + 2
2 = 2 + 0

頭の悪そうな計算をしていますが,この例のように,もし余りがさらに割れるならさらに割る,ダメなら終了という流れが想像できると嬉しいです.

多項式の割り算はどうなるか(本題)

ここでようやく本題ですが,多項式と多項式で割り算することを考えます.
今までのことを使います.つまり,

  • 割るには,(次数と係数を揃えて)引いて消す操作が必要
  • 余りが出て,余りがさらに(他の式でも)割れるなら割る

つまり,多項式中の単項式を引いて消し,余りが出たら,他の単項式を引いてさらに消す.ということです.単項式を消していけば,いずれ割れなくなるはずです(※本当は停止性について考える必要があります).

では具体的な例を考えます.
F = xyzF1 = xy + yz, F2 = xyz + xy で割るとします.

説明都合上F2から割ります.すなわち,F - q1 \times F2 = r としたいです.
F = xyz, F2 = xyz + xy なので, q1 = 1 でそのままxyzが消せそうです.

F - F2 = xyz - (xyz + xy) = -xy

余りの -xy はまだ割れそうです(F1 = xy + yz).

-xy - (-1)(xy + yz) = yz

yz は割れそうにないです.ということで計算終了です.

ん?本当に計算終了なの?

F1 = xy + yz には yz が含まれるから割れる(消せる)のでは?
となります.が,消せないようです.
仮に,消したとすると,新しい式ができ,また消すことができ・・・と無限に操作できてしまいます.答えがあったとしても,答えかどうか判定もできないですし,答えに到達できるかも不明になります.

ここで,順序および単項式の大きさが重要になるはずです.あらかじめ大きさがわかっていて,大きいもので消していけば,この点が解決されるはずです(下記,自身の無い事を参照).

割り算結果が一意でない

先ほどの例ですが,実はF1から割ると,F2から割るときと結果が異なります.
F1で割ると,

F - z \times F1 = xyz - (xyz + yz^2) = -yz^2

となり,結果が異なります.-yz^2はこれ以上F1,F2では割れません.

このように一般には複数の多項式で割ると,結果が一意に定まらないです.
この結果を一意に定めるには,F1,F2がグレブナ基底である必要があります.
また,結果を一意に定める多項式の集合がグレブナ基底です.

自信の無い事(理論)

私自身,書き出したはいいものの,よく理解できてないことです.
すなわち勉強不足な点です.

なぜ大きいものから割っていくのか

前提というか,基本的に割り算のアルゴリズムでは,大きいものから割っていきます.
なぜ大きい物から割っていく必要があるのか?なのですが,正直理解できてないです.直感的には,大きい方から割る方が無駄がなさそう(計算回数が少なそう)なので,大きい方から割ることは自然にも思えますが,なぜと問われると説得力がないです.

文章を作る時に浮かんだことですが,停止性のあたりと関係ありそうです.
私が停止性をちゃんと把握できてないので,そこで理解ができていないと考えられます(要勉強).

係数がなぜ重要なのか

また,このタイプのアルゴリズムでは,おそらく,係数が重要です.
というのも,係数が固定されてないと無理やり割っても何とかなるためだと思います.
上記説明のアルゴリズムでなければ,無理やり 4x^2/3xy = 4x/3y とかみたいに計算できてしまいます.
このとき,係数に着目すると,整数から有理数に係数が変化しています.

上記の割り算アルゴリズムなら,その心配はないはずです(整数-整数=整数となるはずです).
なぜ係数を固定する必要があるのか?という点は理解が足りてないですが,問題設定上係数を固定することが多いように見られます.係数を固定しているならば,無理やり割る事ができない,というわけだと思います.


プログラム

今回はプログラムというより電卓です.足し算引き算して,理論の内容が実装できているように見えればOKという感じです.

次に、多項式での割り算,割る順序で結果が異なる例を計算しています.

多項式の割り算

// 割り算アルゴリズム2

print("コード見ながらの実行を推奨します。")$
print("もしくは、対話モードで実行を推奨します。")$

F1 = x*y + y*z$
F2 = x*y*z + x*y$
F = x*y*z$

/*
// example2
F = xyz を割る
F1 = xy + yzから割り始める

xyz - (w)*(xy + yz)
[...wは適当な値、変数(つまりwは単項式)]
w = z
とすれば、
xyz - (xyz + yz^2) = -yz^2
となって、F = xyz を消せそう

また、-yz^2をF1,F2で消せない。計算終了となる。
*/

R1 = F - z*F1;
// R1 = -y*z^2

/*
// example2
同じく、F = xyz を割る
ただし、F2 = xyz + xyから割り始める

xyz - (w)*(xyz + xy)
[...wは適当な値、変数(つまりwは単項式)]
w = 1
とすれば、
xyz - (xyz + xy) = -xy
*/

R2 = F - F2;
// R2 = -xy

/*
ここでさらに、F1 = xy + yz なので、まだ割れる
-xy - (v)*(xy + yz)
[...vは適当な値、変数(つまりvは単項式)]
v = -1
とすれば、
-xy + xy + yz = yz
となって、-xy が消せそう
*/

R3 = R2 - (-1)*F1;
// R3 = yz

end$

htmlを多項式にしてみた

動機と注意


もし,htmlが多項式になるなら,実際に作るとどうなるのか?

ということで,やってみた.

注意

今回実験的要素が多く含まれます.
さらに結果もたいしたことないので,見る価値も今一つありません.

プログラムはGitHubにあります.

一部,引用だったりコードブロックだったりしますが,引用部はhtmlがうまくコードブロックで書けなかった部分です.

——–

方針


  1. htmlを多項式にする

+ タグを変数に,文章を定数に置換
+ 1行ずつ処理
+ 同じ行の変数と定数は積として単項式に
+ 単項式の和(つまり多項式)としてhtmlを表現

"""
# 単項式にするイメージ!(Python)
# 変数

-> x1

-> x2
<i><i>  -> x3
</i></i> -> x4

# 定数
こんなhtml -> a1
あんなhtml -> a2
"""

単項式1 = 変換する関数("

こんなhtml

")
print(単項式1)
# 表示結果:x1 * a1 * x2

単項式2 = 変換する関数("<i><i>あんなhtml</i></i>")
print(単項式2)
# 表示結果:x3 * a2 * x4

多項式 = 単項式1 + 単項式2
print(多項式)
# 表示結果:x1*a1*x2 + x3*a2*x4
  1. 多項式を計算させてみる

+ 2つのhtml(多項式)でグレブナ基底を計算

  1. 計算結果をhtmlに戻してみる

——–

結果


htmlを多項式で表現

今回使用したhtmlは

<html>
<body>
<p>ここに文章</p>
<i>たとえばイタリックにしたり?</i>
<p><strong>文章を強調</strong>してみたり!</p>
</body>
</html>

と,

<html>
<body>
<p>ここに文章</p>
<p><strong>文章を強調</strong>してみたり!</p>
</body>
</html>

タグ(変数)と文章(定数)は次.

x1 = “<html>”
x2 = “<body>”
x3 = “<p>”
x4 = “<strong>”
x5 = “</html>”
x6 = “</body>”
x7 = “</p>”
x8 = “</strong>”
a1 = “ここに文章”
a2 = “<i>”
a3 = “たとえばイタリックにしたり?”
a4 = “</i>”
a5 = “文章を強調”
a6 = “してみたり!”

このとき,htmlを変換(タグを記号に置き換えるだけ)すると

x1 + x2 + x3*a1*x7 + a2*a3*a4 + x3*x4*a5*x8*a6*x7 + x6 + x5 ,
x1 + x2 + x3*a1*x7 + x3*x4*a5*x8*a6*x7 + x6 + x5

となる.

この2つの多項式でグレブナ基底を計算すると

a4*a3*a2, x1+x2+(a6*a5*x8*x4+a1)*x7*x3+x6+x5

これをhtmlに戻すと

<!– a4*a3*a2 の結果 –>
</i>たとえばイタリックにしたり?<i>
<!– x1+x2+(a6*a5*x8*x4+a1)*x7*x3+x6+x5 の結果 –>
<html>
<body>
してみたり!文章を強調</strong><strong></p><p>
ここに文章</p><p>
</body>
</html>

となる.

——–

まとめと考察?


もうすこしタグが基底っぽく機能するようなモデルにしたかった.
おそらく,一行が一つの単項式になるのが問題で,
一行が一つの多項式になると,もうすこし基底っぽいのがでてくると思われる.

結果がちゃんとhtmlになってない.
これは,順序を正しく与えてあげればそれっぽいのはできる.
ただし,入れ子構造が崩壊しているのは避けられない.
上記と同じく,一行が一つの単項式なのが原因と考えられる.

 

まとめると,今回作った方針でhtmlを多項式化しても特に意味はなさそう.
だが,説明としては使えなくもない・・・のかなぁという感想.

——–

使用したプログラム


今回は乗せると冗長だと判断したため,GitHubに掲載.

WindowsでSage(Bash on Ubuntu on Windows)

概要

Sageは数学向けの計算ソフトウェアで,pythonライクに計算が可能です.
本来,SageはWindowsの対応をしていません.しかし,Windows10の機能である,Bash on Ubuntu on Windowsを使用することで,Windows上でもSageが使用できます.
Bash on Ubuntu on Windowsの導入方法やSageの細かい使用法については他に譲ります.

コマンド

Bash on Ubuntu on Windowsを起動し,以下のコマンドを入力する.

少々時間がかかるので,ネット環境,ノートPCではバッテリに注意してください.
ディスク容量も多め(5GBほど?未検証です.)に空けておくとよいと思います.

sudo apt-add-repository ppa:aims/sagemath
sudo apt-get update
sudo apt-get install sagemath-upstream-binary

備考など

はじめ,公式ページからUbuntu用のパッケージをDLして入れようとしたのですが,いろいろ足りないものが多いらしく,Sageが起動しませんでした.
結果として足りないパッケージを補うよりも,apt-getでSageを入れる方が早かったです.
自分は,デスクトップ,ノートPCで試しましたが両方インストールできました.

通常通り,Sageコマンドでの使用も可能ですし,Sage -nと入力すればノートブック形式での使用も可能です.

輪郭線を多項式で表現

グレブナ基底を勉強していて多項式で何ができるのかという疑問が浮かんだ.
昔,Mathematicaで初音ミクを表現するという話を聞いたことがあったので触ってみました.

Mathematicaで任意画像の輪郭を数式に変換する

メモ

 輪郭線を抽出し,そこから線を近似する方程式を生成するようです.輪郭線のみの情報から方程式を作成するので,色の情報とか質感とかは表現できていないみたいです.
この方程式はperson curvesと呼ばれるもののようですが,大した情報が得られませんでした.もう少し調べた方がよいかもしれないです.参考 person curves

Mathematicaで任意画像の輪郭を数式に変換するにも書いてありますが,GitHub
任意画像の輪郭を数式に変換してプロットする (Mathematica ver.8)のコードを使います(使えます).
説明はMathematica 8用ですが,10でも実行できました.

アイコンのように色と輪郭がはっきりとしているものに対して方程式を作成するのは容易なようです.
逆に,現実の画像で同じ処理をすると,輪郭線の抽出がうまくできず,なんだかわからない線を書く方程式ができてしまうようです.

この方法ならば,任意の物体を方程式として扱えそうですが,技術的な背景やコードの内容をもう少ししらべたほうがよさそうです.

あとは,とりあえず簡単な図形を方程式にして,グレブナ基底に突っ込んで,どうなるのか気になります.

Caffeを(比較的)簡単に扱うGUIツール,作りました.

2017/07/08 追記

こういうツールの需要があるかもしれないですが,もし使うならDIGITSをお勧めします.
NVIDIAが提供するCaffeをラップして使用するGUIで,高機能です.
インストール,使い方は上記リンクGitHub参照です.Caffeがインストールできる程度の知識で十二分に使えるはずです.

学術的だったり,勉強的な意味であればぜひお使いください.参考になれば幸いです.
(追記ここまで)


Screenshot from 2016-03-03 21_45_23.png
Githubにアップロードしてます.どこから見てもベータ版です.

GitHub

推奨はLinux,Ubuntuです.環境はUbuntu14.04です.
言語はpython,GUIはwxPythonです.
動かすには,ターミナルでpython [ファイル名]で直接動かします.

動作としては,caffeインストール時に作成されるツールをそのままコマンドとして実行させています.
なので,コマンドで動かすサンプルと同じ挙動が確認できます.

逆に,python上からcaffeを呼び出して,操作しているわけではないのでそういう類の参考にはならないと思います.実際,多言語のプログラム呼び出しの練習みたいな感じでしたので.
一通り学習まで動く程度にしか作りこまれてないので,作ったといっても多くの人に使ってもらえる代物ではないです.ご了承ください.

UI,パラメータ操作もまだまだ改良する必要がありそうです.
追加機能として,学習精度のグラフとか,ネットワークの構造とか,サンプルで良く見られる内容を実行できるようにしたいです.

wxPythonインストールがそこそこ面倒だった件

Python3系に対応していると聞いて,ちょっと探したところ全くインストールできなかった.
どうしたものかと調べたところ,あっさり通る方法が見つかった.

http://blog.emptypage.jp/archives/298
参考にしました.ありがとうございます.

コマンドプロンプトか,PowerShellに次のコマンドを入力.コピペでも動きます.
管理者権限で実行しています.念のため,管理者で実行したほうが良いと思います.

pip install –user –pre –trusted-host wxpython.org -f http://wxpython.org/Phoenix/snapshot-builds/ wxpython-phoenix

実際に入力した結果が次図.

wxPython_3

とりあえず,importに成功しているので,インストール成功している.
これだけだとちょっと物足りないのでフレーム表示までやってみた.
http://www.python-izm.com/contents/gui/frame.shtml
参考にしました.お世話になります.

表示した結果は次図.
wxPython_3_1.PNG

なぜか応答無しになっているが,動作している.
インタラクティブシェルで動かそうとしたのが失敗だったかも.
一応VisualStudio2015で実行したところ応答無しも出ずに,ちゃんと動きました.

最後に一応動作した環境を載せます.

OS: Windows10 64bit
Python:3.5.1
Anaconda入ってます.verは2.4.0