眠気.jl

投稿=不定期

Juliaで微積CLIを作る(Fire.jl+SymEngine.jl)

動機

関数電卓コマンドラインで出来たらいいなと思った,ありきたりな動機

やっていく

下記をfunc_calc.jlとして保存
今回は小文字アルファベット全部をシンボル扱いする

using Fire
using SymEngine


# シンボル扱いする文字の定義,書き方 1/3
a=symbols(:a); b=symbols(:b)
# シンボル扱いする文字の定義,書き方 2/3
c,d = symbols("c d")
# シンボル扱いする文字の定義, 書き方 3/3
@vars e f g h i j k l m n o p q r s t u v w x y z


"微分する,Argument type Basic is not supported by Fire.jlらしいのでString受取してタイプ変換"
@main function diff_func(f::String, respect_to::String)
    f = Basic(f)
    respect_to = Basic(respect_to)
    result = diff(f,respect_to)
    println(f,"を",respect_to,"で1回微分すると:",result)
end

"代入,この文章はjulia func_calc.jl subsitution --helpで見れる"
@main function subsitution(f::String,respect_to::String,num::Float64)
    f = Basic(f)
    respect_to = Basic(respect_to)
    result = subs(f,respect_to=>num)
    println(f,"において",respect_to,"に",num,"を代入すると:",result)
end

動作確認

微分

:~
$ julia func_calc.jl diff_func 5*x^3+6*x^2+2x+1 x
1 + 2*x + 6*x^2 + 5*x^3をxで1回微分すると:2 + 12*x + 15*x^2
:~
$ julia func_calc.jl diff_func 5*x^3+6*x^2+2x+1 y
1 + 2*x + 6*x^2 + 5*x^3をyで1回微分すると:0

代入

:~
$ julia func_calc.jl subsitution x^2+x+1 x 3
1 + x + x^2においてxに3.0を代入すると:13.0

感想など

Fire.jlでそのまま受け取れると思ったので少し詰まった(typeof()で見ていって解決)

参考URL等

Fire.jl
GitHub - ylxdzsw/Fire.jl: Fire.jl is a library for automatically generating command line interfaces (CLIs) for julia functions.
Fire.jlはgooglepython-fire↓にインスパイヤされたらしい
GitHub - google/python-fire: Python Fire is a library for automatically generating command line interfaces (CLIs) from absolutely any Python object.
SymEngine.jl C++のSymEngineというライブラリのJuliaラッパー
GitHub - symengine/SymEngine.jl: Julia wrappers of SymEngine
Sympy.jl,SymEngine.jl,Reduce.jlで一番スター数が多いのがSymEngine.jl
SymPy.jl vs SymEngine.jl vs Reduce.jl vs - Usage - JuliaLang

JuliaでCLIを作る(Fire.jl)

動機

GoでCLIを作るのが流行ってるので,逆張りしたいから

環境

諸事情でアプデしてない...

julia> versioninfo()
Julia Version 1.1.1

やっていく

呼びたい関数が一つの場合

julia> # press ] here
(v1.1) pkg> add Fire
~$ vim dekiraa.jl

文字列を受け取って表示してみる(※関数が一つの場合)
dekiraa.jlを次のように書く(Fire.jl@mainを見ていく)

using Fire

@main function dekiraaaa(name)
    println(name,"でCLIをつくる?出来らぁ!!")
end

セーブして

~$ julia dekiraa.jl Julia言語
~$ Julia言語でCLIをつくる?出来らぁ!!

できた

複数の関数呼びたい場合

funcs.jlを次のように書く

using Fire


@main function add(num::Integer...)
    println("足し算します :",num)
    println(sum(num))
end

@main function multiple(num::Integer...)
    println("全部かけます :", num)
    a = 1
    for i in num
        a = a * i
    end
    println(a)
end

@main function is_palindrome(str::String)
    reversed_str = join(reverse(split(str,"")),"")
    if reversed_str == str
        println("こ、これは...回文だああああ┗(^o^ )┓三ドコドコドコ┗(^o^)┛三┏( ^o^)┛")
    else
        println("回文ではないですね (´・ω・`)")
    end
end

※複数の関数を定義した場合,その関数を指定しなければ動かない
なのでまず定義した関数を次のコマンドで取得する(覚えてれば必要ないです)

~$ julia funcs.jl --help
See --help of each command for usages
  add
  multiple
  is_palindrome

さらに細かく見る場合は

julia funcs.jl is_palindrome --help
No documentation found.

(定義した場所等うんぬんの文章)

Positional Arguments:
  str: String

確認してみる

~$ julia funcs.jl is_palindrome たけやぶやけた
こ、これは...回文だああああ┗(^o^ )┓三ドコドコドコ┗(^o^)┛三┏( ^o^)┛
~$ julia funcs.jl is_palindrome あいうえお
回文ではないですね (´・ω・`)

できた

感想等

これとZygoteでコマンドライン関数電卓ができそうなのでいずれやります

参考URL

Building A CLI(Command Line Interface ) in Julia with Fire jl [2019]

https://github.com/ylxdzsw/Fire.jl

JuliaのPlot(backend=gr())がtoo many file openで落ちるとき

結論

GR.inline("png")

を追記しよう

動機

Juliaでフレームを増やすと落ちるときがある
例えばこの記事のコードでanim=@animate for i = 1:5000
とすると次のようなエラーが起こる

socket: Too many open files
GKS: can't connect to GKS socket application
Did you start 'gksqt'?

解決策 (してなかった)

mp4にしてみる
gifの部分をmp4にするとうまくいく場合もある
いかない場合もある
(描画できる量は gif<mp4のようだが,どれぐらいまで大丈夫なのかわからなかった)

解決策

GR.inline("png")

を追記したら

anim = @animate 1:5000

落ちることなく最後まで描画できた(mp4,gif共に)
(詳しくはURLを)

最後に

これで突然ランダムウォークを5000歩ぐらい見たくなった時も安心ですね

参考URL(ほぼこのまま)

github.com

github.com

JuliaのPlot(backend=gr())がtoo many file openで落ちるとき

結論

GR.inline("png")

を追記しよう

動機

Juliaでフレームを増やすと落ちるときがある
例えばこの記事のコードでanim=@animate for i = 1:5000
とすると次のようなエラーが起こる

socket: Too many open files
GKS: can't connect to GKS socket application
Did you start 'gksqt'?

解決策 (してなかった)

mp4にしてみる
gifの部分をmp4にするとうまくいく場合もある
いかない場合もある
(描画できる量は gif<mp4のようだが,どれぐらいまで大丈夫なのかわからなかった)

解決策

GR.inline("png")

を追記したら

anim = @animate 1:5000

落ちることなく最後まで描画できた(mp4,gif共に)
(詳しくはURLを)

最後に

これで突然ランダムウォークを5000歩ぐらい見たくなった時も安心ですね

参考URL(ほぼこのまま)

github.com

github.com

vimrcをターミナルでリロードする(vim -c ':source ~/.vimrc | quit')

動機

.vimrcだけを少しだけ書き換えてターミナルでsource ~/.vimrcを実行するとエラーが出た(それはそう,vim起動中にするべき)

vimを(見た目的には)起動せずにやってみる

このようにvim -cでvimコマンドを実行すれば良いと思ったが

vim -c ':source ~/.vimrc'

上記のコマンドだとvimを閉じる処理をしていないので、下記のようにパイプで終了させる

vim -c ':source ~/.vimrc | quit'

エラー無し+ロードに時間がかからなければ見た目的にはvimが起動していないように見える

vim -c ':source ~/.vimrc | sleep 5 | quit'

等で遅延させると開いていることがわかる

感想

面倒くさがらずdotfilesの方でinstall.sh走らせればこんなことには

同じミスをしている方を見つけて勝手に親近感を覚えました

ryutamaki.hatenablog.com

tmg0525.hatenadiary.jp

JuliaでD次元正方格子上のランダムウォークを見る(D=2)

動機

下記のpdfの3/17ページのような正方格子上のランダムウォークを見たくなったので

注意

リントしてないので汚いです
反射壁,吸収壁は考えていません
1辺200の正方格子の中心から300歩やったので奇跡的にはみ出す可能性があります

方針

mutable structとしてParticleを作成して,x座標,y座標,次の方向をもたせる
次の方向=rand(1:4)として→↑↓←を割り振りました,もう少しいい方法もある気がしてます

使うライブラリ

Plotで,Backendはgr()を使う
∵スピード,3D,GUI,を重視したいときはBackendをgr()にすることがおすすめされているので
インタラクティブ性を重視したいとき,速さ重視のとき,綺麗さを重視したいときetc...
結局どうすればいいんだ!早く結論だけ言え!!というせっかちな人のための図があります(For the impatient)
f:id:julialangisthebestlang:20190802194348j:plain

やってみる

using Plots

gr()

ONESIDE = 100

mutable struct Particle
    x::Int8
    y::Int8
    next_direction::Int8
end


particle = Particle(0,0,0)

function assign_direction(Particle)
    Particle.next_direction = rand(1:4)
    return Particle
end

function step(Particle)
    if Particle.next_direction == 1
      Particle.x = Particle.x-1
      return Particle
    elseif Particle.next_direction == 2
      Particle.y = Particle.y-1
      return Particle
    elseif Particle.next_direction == 3
      Particle.y = Particle.y+1
      return Particle
    elseif Particle.next_direction == 4
      Particle.x = Particle.x+1
      return Particle
    else
      return Particle
    end
  end


#300枚のanimを作る
anim = @animate for i = 1:300
    scatter([particle.x],[particle.y],color="blue",xlims=(-ONESIDE,ONESIDE),ylims=(-ONESIDE,ONESIDE),legend=false)
    step(assign_direction(particle))
end

# fps=1秒あたりに見せるフレーム数
gif(anim, "file_name_you_want.gif", fps=20)

結果

f:id:julialangisthebestlang:20190802194520g:plain
random walk

おまけ

scatter!で重ねて書けるので,2個以上の粒子を考える場合はscatter以降をscatter!にする必要がある
意図的にscatter!だけを使ってpathを全部プロットするとこうなる

f:id:julialangisthebestlang:20190802194652g:plain
random walk with path
蛇みたいでかわいい

D=1,2の格子ランダムウォークは原点を無限回訪問するが,D>=3から突然成立しなくなることはよく知られていて例えばD.Williams本にも載ってます
Plot完全理解者になってD=3も可視化したいです

参考

1
オープンコア講座
ランダムウォークと確率論
熊谷 隆(京都大学理学部数学教室)
http://www.kurims.kyoto-u.ac.jp/~kumagai/Open-core-TK.pdf
2
Probability with Martingales(D.Williams)
3
plotのbackendに関して
https://docs.juliaplots.org/latest/backends/

Ubuntu18.04にMeCabとCabochaのインストール

動機

メモ

Mecab

sudo apt install mecab
sudo apt install libmecab-dev
sudo apt install mecab-ipadic-utf8

(Pythonからも使う場合は)

sudo pip3 install mecab-python

Cabochaのインストール

GoogleDriveから,cabocha-0.69.tar.bz2,CRF++-0.58.tar.gzをダウンロード

先にCRF++をインストール

tar -zxvf CRF++-0.58.tar.gz
cd CRF++-0.58/
./configure
make
sudo make install
sudo ldconfig

Cabocha

tar -jxvf cabocha-0.69.tar.bz2 cabocha-0.69/
cd cabocha-0.69/
./configure --with-mecab-config=`which mecab-config` --with-charset=UTF8 
#mecab設定
make
sudo make install