Mathematica Programming on RaspberryPi Zero

RaspberryPi Zeroが出た。Mathematicaを動かす。勉強会も開こう。

5月14日に第3回目のMathematica ワークショップを茅場町Co-Edoで開いた

第2回目は平日の夜に開催したら、キャンセルが相次いで、ただ一人残った参加予約者も、一人ではどうも、ということでキャンセルとなってしまったという経緯があったので、第3回目は休日の午後3時からということとしたら、5人程の参加者があった。

 

参加者に休日の午後と聞いたら、平日は都合がわるいということだった。平日の夕方に開いた第1回目の参加者は、平日の方がよい、という答えだったので、今後は適宜開くことにしようと。

 

参加者の経験やモチベーションの方向も色々であったので、これも今後また臨機応変に内容を変えていくのがよかろうと。基本は参加者の意見を聞くことであるな。

 

ところで、MacBook Airをディスプレイに繋いだら、ディスプレイの分解能に合わせて普段の画面より高い分解になったので、ちょっと驚いた。

Wolfram Communityに

community.wolfram.com

という記事をアップした。OOPを使って、三台のRaspberryPi Zero上のMathematicaを並列して動作させるというプロジェクトの結果だ。

ただ、Wolframには、並列計算サーバーの下でカーネルを管理しながら、並列計算を実行するというポリシーがあって、この記事はその間隙を突くものとなっているので、手法そのものより、ポリシーに反するのではないかという議論の起こる可能性もある。

まあ、そうなっても良いかとは思っていて、これを実現したOOPが広がるためなら、何かあっても仕方がない、とは思っている。

Mathematica on RaspberryPi Zero ワークショップのためのプログラム例

 

ワークショップのための

Mathematica の短いプログラム例 

kobayashikorio@gmail.com

2017/4/5

 

以下のプログラムは、Macで閲覧しながら、コピーし、VNCビューワーで動かしているMathematicaのノートブックにペーストできる。

 

1. RaspberryPi Zero は強力ではないが非力でもない

 

10万項からなる多項式の展開

Timing[Length[Apply[List,s=Expand[(w+x+y+z)^52 w(x+1)(y+2)(z+3)]]]]

 

変数が4つあり1万項からなる多項式因数分解

Timing[{Length[Apply[List,s=Expand[(w+x+y+z)^23 w(x+1)(y+2)(z+3)]]],Factor[s]}]

 

次数10万の疎な多項式の整数根の計算

s=x^(10^5)-123456 x^100+789x^11;

f=s/.x->987654321;

Timing[Reduce[s-f==0,x,Integers]]

 

100万までの全素数の計算

Timing[Table[Prime[n],{n,PrimePi[10^6]}];]

 

10×10の記号行列の行列式の計算

m=Table[ToExpression["x"<>ToString@i<>ToString@j],{i,10},{j,10}];

Timing[d=Det[m];]

 

1千万個の要素からなるリストの並べ替え

Timing[Sort[Range[10^7,1,-1]];]

 

100万個の文字からなる文字列の検索

s=StringReplace[ToString[RandomInteger[5,10^6]],", "->""];

Timing[Length[StringCases[s,"0000000"]]]

 

 

例2 問題を解くための各種方法

問題:10 未満の自然数のうち、3 もしくは 5 の倍数になっているものは 3, 5, 6, 9 4つがあり、 これらの合計は 23 になる。 同じようにして、100, 000 未満の 3 5 7 の倍数になっている数字の合計を求めよ (Project Euler #1 の拡張問題)。

n=10^5-1;

Total[Select[Range[n],Divisible[#,3]||Divisible[#,5]||Divisible[#,7]&]]

 2714264277

 

Total[Range[n]/.x_/;!Divisible[x,3]&&!Divisible[x,5]&&!Divisible[x,7]->0]

 2714264277

 

Total[Select[Range[n],Function[y,Apply[Or,Map[Function[x,Divisible[y,x]],{3,5,7}]]]]]

 2714264277

 

Total[Table[If[Divisible[i,3]||Divisible[i,5]||Divisible[i,7],i,0],{i,n}]]

 2714264277

 

(s=0;Do[If[Divisible[i,3]||Divisible[i,5]||Divisible[i,7],s+=i],{i,n}];s)

 2714264277

 

Sum[If[Divisible[i,3]||Divisible[i,5]||Divisible[i,7],i,0],{i,n}]

 2714264277

 

(For[s=0;i=1,i<=n,i++,If[Divisible[i,3]||Divisible[i,5]||Divisible[i,7],s+=i]];s)

 2714264277

 

Total[Reap[Scan[If[Divisible[#,3]||Divisible[#,5]||Divisible[#,7],Sow[#]]&,

Range[n]]] [ [2,1] ]

]

 2714264277

 

Fold[(#1+If[Divisible[#2,3]||Divisible[#2,5]||Divisible[#2,7],#2,0])&,0,Range[n]]

 2714264277

 

(f[p_]:=(p*Quotient[n,p]*(Quotient[n,p]+1)/2);f[3]+f[5]+f[7]-{f[3*5]+f[3*7]+f[5*7]}+f[3*5*7])

 {2714264277}

 

 

 

例3 秒針時計

 ここでは時計の秒針のみを表示するサンプルを提示する。

s=N[Table[{ Sin[2Pi k/60],Cos[2Pi k/60]},{k,0,59}]];

Show[{ListPlot[s,AspectRatio->1.0,Ticks->None],

Graphics[{Red,Arrow[{{0,0},

Dynamic[s[[

t=Clock[{1,60,1},60]]]]}]}]},

ImageSize->200]

 

 

 

例4 文字を要素とした正則行列

a={{不可,,,},{,不可,,},{,,不可,},{,,,不可}};

a//MatrixForm

 ({

  {不可, , , },

  {, 不可, , },

  {, , 不可, },

  {, , , 不可}

 })

Simplify[a .Inverse[a]]==Simplify[Inverse[a] .a]==IdentityMatrix[4]

 True

 

例5 wikiquoteを読み込む

x@a__:=StringCases@a

y@c__:=StringReplace@c

z@e_:=Shortest@e

 

s=Import["http://en.wikiquote.org/wiki/Steve_Jobs","Source"];

s1=StringCases[s,"<li><b>Was"~~__~~"editsection"];

s2=StringReplace[s1,{"<li>"->"+","<div"~~__~~"</div>"->"",Shortest["<"~~__~~">"]->""}];

s3=Flatten@StringCases[s2,Shortest["+"~~__~~"+"]];

s4=StringReplace[s3,"+"->""];

RandomChoice[s4]

 We believe it's the biggest advance in animation since Walt Disney started it all with the release of Snow White 50 years ago.

 

 

RaspberryPI Zeroを用いたMathematicaクラスタの構築

このところ、RaspberryPI Zero上のMathematicaをホストのMathematicaからコントロールする方法を考え続けていたが、概ね出来上がった。概ねというのは、複数のRaspberryPi ZeroをUSB HUBを通して、これをホストにしたMacBookに繋げると、いかに小さい電力しか必要としないRaspberryPi Zeroとは云え、3台だと不安定になってしまって、ブーツアップまで自動化するのは、ちょっと困難があるからだ。

ハードウェア的にはごく簡単なのであるが、ソフトウェア的にはOOPとnetcatとAssociationとProcess関数群を使っていて、出来上がってしまえば簡単なのであるが、作るまでが大変だというプログラムだった。

 

RaspberryPi Zeroの並列化

HAT (Hardware Attached on Top) というメーカーが、RaspberryPi-Zeroを4枚並べることのできる、ボードを提供していて、恰好が良いので購入してみた。恰好は良かったのだが、実際のところどうなのかが分からなかったということもあって、人柱となってみたのだった。型名は8086-001 Cluster HATである。

 

到着したので眺めてみると、ボード単独では使えないようで、コネクタによってベースとなるRaspberryPiが別途必要となるらしいことが分かって、改めてRaspberryPi Zeroとコネクタのハンマリングツールを発注した。ハンマリングツールというのは、コネクタを圧入する代わりに、ハンマーで叩き込むための治具である。

f:id:sanpodo:20170304184217j:plain

 で、Zeroにコネクタを取付けて、Cluster HATと接続したのだが、うまくコントロールできない。ベースのRaspberryPiのGPIOを制御することで、Zeroの電源をコントロールするようなのだが、反応しないのだ。

 

散々やってみて、結局Cluster HATのホームにある接続図や説明が、手持ちのボードと全く異なることが判明したのだ。ボードを虫眼鏡で見て、配線の具合を調べて、確定したのが、以下の通りだ。

 

alert -> GPIO 5

p1 -> GPIO 6

p2 -> GPIO 13

p3 -> GPIO 19

p4 -> GPIO 26

GPIOはbashからもコントロールできて、pin 19をHighにするには、

echo "19" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio19/direction
echo "1" > /sys/class/gpio/gpio19/value

これをLowにするには
echo "0" > /sys/class/gpio/gpio19/value

pin19から読み込むためには、
echo "in" > /sys/class/gpio/gpio19/direction
cat /sys/class/gpio/gpio19/value

とすればよいのだ。 

結局のところ、ボード上に搭載するZeroのパワーは、ベースのRaspberryから供給するようになっているようで、これでは、ベースにZeroを用いたのでは容量不足になるのは明らかだ。となれば、素直にZeroをUSBハブに複数繋げればよいことになる。ただそれだと不格好になってしまうな。