Pythonで数値解析〜sympyでできることを少し試してみた〜
どうも。
昨日は勉強できなかったのですが、今日から復活です!
とは言ったものの夕方まで部活で拘束されてしまったので、今日はほんのちょっとしかpythonに触れていないのですが、そのほんのちょっと体験したことをここでは書きたいと思います。
先日書いたブログの中では方程式を解いてみたことについて書きましたが、今回は積分についてやっていこうと思います。
実は先日軽くsympyを用いるときに参考にしたページを眺めて「積分は1変数における積分にのみ」対応しているのかと思いきや、とんでもない。2変数以上の積分にもしっかり対応していました!早速参考までにいくつかを例に示してみます。
・
#python3 >>>from sympy import * >>>var('x') #xを変数とする >>>var('y') #yを変数とする >>>integrate(v**2, x, y) #y^2をxとyで積分 x*y**3/3
ちゃんと結果が得られた!
・
#python3 >>>from sympy import * >>>var('x') #xを変数とする >>>var('y') #yを変数とする >>>var('z') #zを変数とする >>>integrate(x*y*z, x, y, z) #xyzをx, y, zで積分 x**2*y**2*z**2/8
これもちゃんと結果が得られた!
これらからsympyによってpythonでの重積分の計算が可能であることがわかったのですが、これを知るきっかけとなったページを載せておきます!
こちらです → http://www.sympygamma.com/
英語で書かれていますが、かなりsympyで使える機能が載っているので是非ともpythonで数値解析してみたい人などには見ていただけたらと思います( ̄▽ ̄)
こうやってみるとプログラミングを学ぶ上でとことん追求し始めると英語で書かれたウェブサイトなどに書いてあることを理解することで学べることが多いので僕も英語をスラスラ読めるような英語力を身につけないとダメだな〜と感じてきています(笑)
それでは、また。
Pythonで数値解析〜代数計算も可能な環境にしてみた〜
どうも。
今日は行列計算やグラフを描くだけではなく、代数計算(微積分や極限など…)をできるようにsympyライブラリを導入してみました!
Q. sympyライブラリはどうやって導入するか?
やり方はとても簡単で自分の場合はある程度pythonに対する環境は整っていたので次の1行を実行するだけで終わりました(笑)
pip install sympy
これだけで済むようにする方法を僕から(僕は情弱なので…)詳しく説明することはできませんので、過去の記事で一通りのPythonで数値解析をする環境を整える手順などを紹介しているので、それを参照しながら同時に導入していただければいいのではないかと思います。
ただし、ここで注意が(僕が陥っただけのことですが…)
僕のPCではpythonは2系も3系も使える環境で、今回はpipでインストールしたので2系で扱えるようになっているだろうと勝手に思い、いざpythonと打ち込み、sympyの力を体感しようと思ったら扱えませんでした(笑)何故だろう?と思い、python3で実行してみたところ扱えました( ´ ▽ ` )
ここからはsympyを使って代数計算させてみようと思います( ^ω^ )
今回は方程式を解くのを例にやってみます。
・方程式を解く
ここでは方程式の解を求めてみました。求める手順は次の通りです。
$python3 >>>from sympy import * >>>x = Symbol('x') #xを変数として扱う >>>solve(x**4 - 1, x) [-1, 1, -I, I]
基本的に関数solveはsolve([解を求めたい式], [変数])として使われる。また解を求める際、解を求めたい式=0として処理される。
大学でmathematicaを実験で扱ったのですが、それを使えばいいじゃないかとも思ったのですが、次数の高い方程式の解を求めようとすると結構(いや、かなり)面倒臭いのでmathematicaは偉大だな、とか感じました。
次数の高い方程式の解(というより近似値かな?)を求める方法を調べたらこのページを見つけたので参考までに。
API docs for “sympy.simplify.rootof.RootOf”
今後は以下のものを参考にしながら面白いことができればと思います。
3.2. Sympy : Python での代数計算 — Scipy lecture notes
それでは、また。
Pythonで数値解析〜matplotlibを使ってみた〜
どうも。
今日は昨日、情弱なりに頑張ってnumpyやscipy、matplotlib、ipythonなどをせっかく入れたのでこれらを少し体感すべく簡単なプログラムを書いて動かしてみました。
今回以下のものを参考にしました。
2015 年度プログラミング言語演習 Python — 2015.ProgramingLanguage 0.4 ドキュメント
今回はsin波を16等分にサンプリングしてその結果をもとに曲線を描くというものを普通にpython(ここではpython2.7.10)で実行するパターンとipython(ここではipython3)を用いてやるパターンの2通りでやってみました( ´ ▽ ` )
まずはpythonで実行する場合を紹介します。
$python >>>import numpy as np >>>import scipy as sp >>>import mayplotlib.pyplot as plt >>>N = 16 >>>t = np.arange(N) #順番にシーケンスを生成(0〜15) >>>x = np.sin(2 * np.pi / N * t) >>>plt.plot(t, x) #グラフをプロット >>>plt.show() #グラフを表示
すると、次のようにsin波の波形が表示されます。
しかし、この方法だとインポートしたりする作業がすごく面倒くさいですよね?ここでipythonを用いた場合はどうすれば同様のことができるか確認しましょう。
$ipython3 --pylab >>>N = 16 >>>t = arange(N) >>>x = sin(2 * pi / N * t) >>>plot(t, x) #グラフをプロット&表示
ipythonではpythonだと8行書いて行っていたことが4行書いただけで実行することができました。すっきりしているかどうかで言えばipythonの方だと僕は個人的に思います( ^ω^ )
ただ、きちんとnumpyやscipyなどを使ってるという実感が出るのはpythonで上記のように書いて実行する方だと思いますが(笑)
しかーし!実はpythonで実行しようとしてもipythonのようにインポートを3つも行わなくても書く方法がありました。それが次の通りです。
$python >>>from pylab import * >>>N = 16 >>>t = arange(N) >>>x = sin(2 * pi / N * t) >>>plot(t, x) >>>show()
インポートするための文を減らしたり簡潔に書けたりするので今後、本格的な数値解析をする場合は有効かもしれないですね( ^ω^ )
自分はまだ勉強して間もない(環境を整えるのも含め2日しか経ってない…)のでこれ以上の言及はしません(笑)
余談ですが、昨日のこの記事↓の中でも言いましたが、gfortranの導入を中断していました。
mathharachan.hatenablog.com
で、コンパイルなどで必要な場面があると思いきや、当分なさそうなのでgfortranの導入は必要になった時に入れるスタンスでいこうと思います(笑)
もし入れる時になったら、導入する際に奮闘(するはず)した事なども紹介できればと考えてます。
次回はもっとnumpyやscipyなどを利用した簡単めなプログラムの実行の体験を発信したいと思います。
それでは、また( ´ ▽ ` )ノ
Python始めるぞ〜初期導入編〜
どうも。 今日は本格的にPythonによるプログラミングをするための環境を整えるのに奮闘した(大袈裟)ので、その流れ?を紹介できればと思います。
とは言うものの今回環境を整える場がMacbook AirなのでデフォルトでPython2.7.10が入って、かつ、研究室の先輩にHomebrewを使えるようにしてもらっていた(自分自身がかなり疎すぎる)ので、3系の環境を整えるとともにPythonで数値解析ができるようにNumpyやScipyなどを導入するところまでやりました。 今回は以下の記事を参考に導入しました。
基本的には参考にしたブログを見てもらえればほぼ確実に導入できると思われます。 何せ自分には環境を整える上での知識があまりにも無いため説明は省略させていただきたいと思います(笑)
ただ、Fortranをインストールする際に自分の場合はエラーが出たので、エラーを読み指示通り以下のコマンドを実行しました。
実行したはいいもののものすごく時間がかかりました(笑)
最終的にこの作業だけで72分も掛かったとのことで…もっと良い手順があると思いますので、きちんと調べると良いかもというのが僕のここで伝えたいことですね(笑)
そして、fortran入れようと思っていたがここでまさかの大ブレーキ(笑) 残念ながら記事を参考したにも関わらず、自分の場合エラーが解消できずにgfortranをインストールする段階を飛ばしてしまいました。。。 自分の情弱性と知識のなさが招いた事故なので参考にした記事がダメということではありません! 一応、インストーラーをダウンロードしたので解決しようと思えばできる気がするんですが…ここでは省略させていただきます。申し訳ないです。。。
ここを飛ばすとあら不思議、何事もなく環境は整い、参考にした記事の内容通りにsin波も表示することができ、とりあえず一安心。
ということで、次回はgfortranを確実に入れたか確かめること、実際にパッケージを使って体感してみることが今後の課題だと思うので解決したり体感したり何か進捗があればここに書きたいと思います( ^ω^ )
それでは、また( ´ ▽ ` )ノ
体の訛りが…
どうも。
最近、慣れないブログを凝った形で書いた結果、燃え尽きてしまいました(笑)
なので、今回はゆるふわな感じで短めに。
僕は陸上競技部に所属しているのですが、実は2月の頭からシンスプリントの痛みが起きてしまい、最近まで走れず上半身強化や下半身部のストレッチなどをして過ごしていました。
ようやく、ジョグをしても痛みが生じなくなったので、久しぶりに少し長めのジョグをしました。
するとどうでしょう、、、体が重くなり、心肺機能も著しく低下。
挙げ句の果てには疲労があったのか寝転がったら寝落ちするという形で昼寝をしてしまうという体力の落ちっぷり( ;´Д`)
いやー、マズイ。ただただ焦りの心境。
2週間後には春合宿を迎えるのだがおそらくベストパフォーマンスを発揮できない分、万全の状態で臨む時のように追い込むことが困難なので、焦る気持ちを抑えつつ3月は復活を狙いに行きたいと思います。
全然ゆるふわな感じが出ませんでしたね(笑)
友人にPythonやろうよ!と何故か言われているので、明日あたり始めようかなと思います。参考ページなどもブックマークに入れて準備万端!
Pythonの事も無線通信の勉強の合間で少し書ければなと思います( ^ω^ )
それでは、また。
最近学んだ事シリーズ:モンテカルロ法によるシミュレーションで用いる乱数の生成
みなさん、どうも。
今朝?投稿した「最近学んだ事」をシリーズ化してみようかなと思い、今日は2度目の投稿を決意しました(堅苦しい挨拶…)。
と、シリーズ化って言っても興味を持ってもらえるような記事を書けるか不安ではあるの(そもそも続ける事ができるかどうか怪しい)ですが、気長に見守っててくれると有り難いです(笑)
さて、タイトルのせいで自分からものすごくハードルが上がってる(?)気がしますが、ここでは自分が乱数生成の関数を学ぶ際に参考にしたものを紹介しながら書いてみたいと思います。
Q. そもそも何故、モンテカルロ法を学ぼうと思ったか?
僕は今後、無線通信をテーマにした研究室に配属されるため、データを取るためにはプログラムによるシミュレーションを行わなければいけません。しかも、論文などを見てみるとモンテカルロ(Monte Carlo)法が用いられていたので勉強しなきゃと思いました。
いよいよ、本題。
僕はこちらの本を使い、参考にしながら学びました。
- 作者: 神谷幸宏
- 出版社/メーカー: コロナ社
- 発売日: 2010/11/22
- メディア: 単行本
- 購入: 1人 クリック: 5回
- この商品を含むブログ (2件) を見る
この本は自分は残念ながらC言語にしかまともに触れていなかったため、C言語を用いた無線通信に関するシミュレーションを題材に扱ってる本はないか、探してみたところ見つけて即購入したものです。変調方式からフェージングなど無線通信に関する基礎事項の説明も書かれているので、無線通信に関する参考書としてオススメです。
無線通信において乱数を用いる場面はどこだろう?それは主に信号(雑音も含む)です。
ここでの信号はほとんどの場合、信号の確率密度関数がガウス分布(式(1)に示す)に従うものとして扱われます。
は信号値、は信号の平均値、は信号の電力を表す。
無線通信のシミュレーションの場合、専ら正規分布に従うという条件下を考える場合が多いので平均値は0、電力は1として扱われる場合がほとんど。こういった状況で誤り確率の値がシミュレーションされます。なので、正規分布に従った乱数(正規乱数)の生成方法を学びました。
また、無線通信において「フェージング」と呼ばれる干渉現象を考える場合も多く、このフェージング環境下においては信号の振幅値の確率密度関数がレイリー分布(式(2)に示す)に従うものとして扱われる。
ここでのは信号の実部と虚部を用いて、と表される。
さらに 、とはともに平均値0、分散1の正規分布に従うものされる場合が多いので、今回はその条件下で乱数生成を学習した。
実際に乱数を生成するためのCプログラム(正確には関数ですね)は次の通りです。
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> //一様乱数発生させる関数 double randU(void){ return ((double)rand() / (double)RAND_MAX); } //標準正規分布に従う乱数発生させる関数 double randN(void){ double s, r, t; s = randU(); if(s == 0.0) s = 0.000000001; r = sqrt(-2.0 * log(s)); t = 2.0 * M_PI * randU(); return (r * sin(t)); } //正規化されたレイリー分布に従う振幅値を発生させる関数 double rayleigh(void){ return sqrt(pow(randN(), 2.0) + pow(randN(), 2.0)) * sqrt(0.5); }
このプログラムに関していろいろ書こうかと思ったのですが、ここまで書いてきてすごく疲れてしまったので参考ページを掲載します(笑)
参考ページ↓
C言語による乱数生成
このページにはレイリー分布については書いてませんので注意してください。レイリー分布に関しては先程紹介した本に記載されていますので、そちらを確認していただければと思います。しかし、レイリー分布に関しては何故この式でいいのだろう?と思ったのでその事に関してだけ。。。
この疑問については…よくよく考えてみると振幅値、つまり、の値なので単純にに関する式から考えて、上記のプログラムのようになったと理解できました。冷静に考える重要さが身に染みましたね(笑)
と、まぁこんな感じで少しずつですが勉強していってます。
かなり長々と書いたつもりですが、僕が不慣れすぎて雑になってしまいました(⌒-⌒; )
今回は大目に見てもらえると今後も続けられると思います(笑)
それでは、キリが悪いのですがこの辺で!
最近学んだ事:リレー伝送方式
こんにちは。
今日のこの記事に関しては日本語で書きたいと思います(笑)
先日、僕の汚い英語(ちゃんと文章として意味を成しているのかわからないレベル)で書いたのですがRFエナジーハーベスティングを用いた協調通信に関する論文を読んだ事を紹介しました。
その論文の内容を正しく理解するために、リレー伝送について自分なりに調べて学びました(論文の中でも説明が書いてあったのですが、自分の英語の理解力が乏しく…涙)。
それでは簡単に自分の言葉で書いてみようと思います。
Q. そもそも何故リレー伝送を用いることを視野に入れる?
近年ではスマホの普及により、より多くの人が容量の大きいもののやり取りがしやすくなり、実際に音楽や動画の共有など世界規模でされている。しかし、このようなやり取りする規模、ユーザー数が大きくなることで高速かつ大容量通信の実現が急務となっている。もちろん、基地局を増やせばいいのでは?と考えてしまうが、コストを考えるとあまり現実的ではない。また、高速で通信をするには高周波信号を送受信できる環境も必要となる。そこで、この大きな2つの問題点を解決し得るものとして「リレー伝送方式」である。
リレー伝送方式は信号の減衰を抑えることができ、高周波の信号も通信しやすくなる。また、基地局を増やすのではなくリレー局を設置していけばいいので用いる基地局の数も減らすことができ、コストも減らせる。故に注目されるのである。
Q. リレー伝送方式とは?
リレー伝送方式とは簡単に言えば、基地局-宛先間での通信を行う際に直接的に通信を行うのではなく、リレー局を中継して通信を行うものである。
リレー伝送方式には主にAF(Amplify and Forward)リレー伝送方式と呼ばれるものとDF(Decode and Forward)リレー伝送方式と呼ばれるものの2つがあります。厳密に言えば他の方式もあります。ここではこの2つの方式について説明したいと思います。
1. AFリレー伝送方式
この伝送方式では送信された信号をリレー局で受け取り、リレー局で受信信号を復調せず信号の電力を増幅し再送する。この伝送方式の利点は信号の電力を増幅させるだけなのでコストがあまりかからず、この処理にかかる時間も少ないため処理による遅延時間が小さいところである。逆に欠点は希望する信号以外の信号(主に雑音)も増幅されてしまうところである。
2. DFリレー伝送方式
この伝送方式では送信された信号をリレー局で受け取り、その信号を復調した上で再度符号化して再送する。この伝送方式も利点は信号の干渉成分が除去されて高品質な通信が可能になるところである。逆に欠点は中継での処理が多いため遅延時間が増加してしまい、かつ、制御が複雑化してしまうところである。
まだまだ自分も勉強し始めた身なので、ここで紹介した中で誤りがあるかもしれませんが、僕が勉強した限りではリレー伝送方式はこういったものです。間違っていそうだったら、各々で調べてもらえればと思います(⌒-⌒; )
もっともっと勉強し、このブログで書いていければいいのかなと思います(笑)
それでは、また。