sikino のすべての投稿

フリーソフトの紹介

全てwindows10上で動きます。
Microsoft Powerpoint, Word以外は無料です。

  1. キャプチャ -Setuna2
  2. ランチャー -RocketDuck
  3. メール管理 -Thuderbird
  4. テキストエディタ -Sublime Text
  5. 文書作成 -Microsoft Word, -LaTeX
  6. グラフ作成 -gnuplot
  7. PDFビューワ- SumatraPDF
  8. PDF結合、分割等- pdf_as
  9. 画像圧縮 -Caesium portable
  10. 画像編集 -Microsoft Powerpoint, -GIMP
  11. EPS画像への変換 -Metafile to EPS Converter
  12. GIF画像作成、編集 -Giam
  13. 画像ビューワ -Leeyes
  14. 音楽再生 -VLCメディアプレイヤー
  15. 音楽ダウンロード -Download helper(firefoxアドオン)
  16. 動画再生 -GOMplayer
  17. 動画変換、音楽の抽出 -Craving Explorer
  18. mp3の音量調節 -MP3Gain
  19. 動画キャプチャ -windowsキー+g
  20. 動画編集 -Aviutl
  21. PCの情報取得 -Speccy
  22. PC間のデータ移動 -IP Messenger
  23. PCのデータ削除 -Bleachbit portable
  24. PCのウイルス除去 -Norton Power Eraser
  25. アプリケーション情報 -Process Explorer
  26. 広告除去 -Adblock Plus, ublock
  27. 仮想環境 -Vmware Player
  28. オフラインゲーム -Track Mania Forever
  29. オフラインゲーム -SCP Containment Breach
  30. マウスオーバー英和辞書 -mouse dictionary
  31. 数式処理システム -maxima
  32. リンク集

  33. 計算ソフト -wolfram alpha
  34. グラフ描写 -gnuplot onlice
  35. latex記号検索 -detexify
  36. グラフの数値化 -WebplotDigitizer
  37. 暇つぶし用 -SCP財団

1. キャプチャ


Setuna2
http://www.clearunit.com/clearup/setuna2/

説明

画面上の任意の範囲を画像として保存するソフトウェアです。
画像保存だけでなく、キャプチャした領域は半透明で常に画面最前列に現れます。
そのため、アプリケーション間を行ったり来たりすることなく欲しい情報を表示させておけます。
現在サイトが閉鎖されている…ようです。


2. ランチャー


RocketDuck
https://rocketdock.com/

説明

ランチャーです。Macにある感じのやつです。画像の上に出てる枠を追加します。
良く使う実行ファイルやフォルダへのショートカットをデスクトップ上以外に表示させることが出来ます。


3. メール管理


Thuderbird
https://www.mozilla.org/ja/thunderbird/

説明

複数のメールアドレス(例えばyahoo,gmail,hotmailなど他社サービスであっても)をまとめて管理できます。
インターネットブラウザを立ち上げないでメールを見られます。


4. テキストエディタ


Sublime Text
https://www.sublimetext.com/3

説明

プログラムを書くためのエディタです。


5. 文書作成


Microsoft Word, LaTeX

説明

文章を書くためのソフトウェアです。
数式や記号のようなものを表現したければLaTeXが良いです。
LaTeXは導入までが難しいです。導入はEasyTeXが比較的簡単でしょう。
EasyTeX


6. グラフ作成


gnuplot
http://www.gnuplot.info/

説明

グラフを描く為のソフトウェアです。
windows用に作られたwxtターミナルはアンチエイリアスが聞いているので、滑らかなグラフが表示されます。
eps,gif画像も作ることが出来ます。


7. PDFビューワ


SumatraPDF
https://www.sumatrapdfreader.org/free-pdf-reader.html

説明

PDFファイルを開くためのソフトウェアです。
PDFファイルを見るだけしか出来ませんが、起動が高速で、動作中に固まったことはありません。
PDFビューワとして有名なソフトウェアAdobe Readerがありますが、起動までに数秒~数十秒かかり動作も重いです。


8. PDF結合、分割


pdf_as
http://uchijyu.s601.xrea.com/wordpress/pdf_as/

説明

2つのPDFファイル同士を結合、追加、分割、抽出、削除、回転するソフトウェアです。
PDFファイル同士の結合を行うためだけにAdobe Acrobatを買う必要はないのです。非常にシンプルで使い易いです。


9. 画像圧縮


Caesium portable
https://saerasoft.com/caesium/

説明

jpg,png等の画像を圧縮し,容量を減少させます。
インストールなしに使うことができ、手軽に使えます。


10. 画像編集


Microsoft Powerpoint
GIMP
https://www.gimp.org/

説明

・Powerpoint
本来プレゼンテーションを作るためのソフトです。
画像や写真に文字を加えたい時などに、ppt上で編集→図として保存を行うと比較的簡単に編集できます。

・GIMP
画像編集用ソフトです。
フォトショップ並みの編集が可能ですが、慣れ、知識、技術が必要ですので、初心者向けではありません。


11. EPS画像への変換


Metafile to EPS Converter
https://wiki.lyx.org/Windows/MetafileToEPSConverter

説明

右クリックでコピーした画像を、このソフトウェアに貼り付けをすることでその画像のEPSファイルを生成します。非常にお手軽にEPSファイルを作ることが出来ます。


12. GIF画像作成、編集


Giam
http://furumizo.net/tsu/giamd.htm

説明

GIF画像の編集ソフトです。
GIF画像を作ったり、編集を加えたり、コマ送りとして見ることが出来るソフトです。
ある特定の場面を画像として保存することも出来ます。


13. 画像ビューワ


Leeyes
http://www3.tokai.or.jp/boxes/leeyes/

説明

画像、または圧縮ファイルにおさめられた画像を解凍することなく見ることが出来る画像ビューワです。
プラグインを入れることによりrarなどの様々な画像形式に対応することが出来ます。


14. 音楽再生


VLCメディアプレイヤー
https://www.videolan.org/vlc/index.ja.html

説明

音楽、動画再生ソフトです。


15. 音楽,動画ダウンロード


Download helper(firefoxアドオン)
https://addons.mozilla.org/ja/firefox/addon/video-downloadhelper/

説明

firefoxのアドオンで、あらゆるサイトの動画のダウンロードが可能です。
3つの風船がトレードマークで、動画配信サイトに行きこの風船をクリックし、動画ダウンロードを行います。
動画のダウンロードは、著作権法に抵触しないようにしましょう。
※ブラウザに付随するコンソールでも、メディアファイルのダウンロードが可能です。


16. 動画再生


GOMplayer
http://www.gomplayer.jp/

説明

動画再生ソフトです。
コマ送り、スロー再生、逆再生、左右反転、上下反転が出来ます。
広告が邪魔ですが、これは環境設定→一般→スキンからクラシック[フォルダ]を選ぶと広告は消えます。


17. 動画変換、音楽の抽出


Craving Explorer
https://www.crav-ing.com/

説明

本来はインターネットブラウザです。
Craving explorerに付属する、オフライン状況下でも使える動画変換機能がシンプルで優秀です。
以前は動画、音楽ダウンロードを売りにしていたブラウザでしたが、著作権の問題からダウンロード機能が除去されていたようです。
2017年現在、ホームページを訪れると再び動画をダウンロードできる仕様になったようです。


18. mp3の音量調節


MP3Gain
http://mp3gain.sourceforge.net/

説明

mp3ファイルの音量を変えるソフトです。
複数ファイルの音量の均一化をすることも出来ます。
エンコードするわけではないので、操作は一瞬で完了します。


19. 動画キャプチャ


oCam
http://ohsoft.net/eng/

説明

画面を動画としてキャプチャします。
録画後に広告が出ますが、録画した動画に広告は出てきません。

windows10ならば、
windowsキー+g
でデフォルトでキャプチャ用のソフトが入っていますので、こちらがよいでしょう。


20. 動画編集


Aviutl
http://spring-fragrance.mints.ne.jp/aviutl/

説明

avi動画の編集を行えます。
全く別の2つの動画から比較動画を作ったり、文字を入力したりできます。
初心者向けではありません。編集には慣れが必要です。
プラグインを用いれば、mp4を読み込ませ、編集し、mp4で出力させることが出来ます。
詳しい説明は
VIPで初心者がゲーム実況するには https://www18.atwiki.jp/live2ch/pages/165.html

ニコニコ動画まとめwiki http://nicowiki.com/AviUtl.html
をご覧ください。


21. PCの情報取得


Speccy
https://www.piriform.com/speccy

説明

PCの構成情報を綺麗なウインドウで教えてくれるだけのソフトウェアです。
例えば、OS, CPU, メモリ(DDR3など)、モニターの型番、マウスの情報、IPアドレス等々です。
スマートです。


22. PC間のデータ移動


IP Messenger
https://ipmsg.org/

説明

ルーターを介してLANでつながったPC間のデータ移動を行います。
インターネット環境は必要ありません。ネット接続もしません。
高速、セキュリティともに良いと思います。開発から20年経過した現在(2017/09/08)でも更新がなされています。


23. PCのデータ削除


Bleachbit portable
https://www.bleachbit.org/

説明

PCに存在するゴミファイルを消去して空き容量を確保します。
ブラウザのキャッシュ、一時ファイル、データを揃えて空き容量を確保したりできます。
アプリケーションごとにどういったファイルを消すか指定することが出来ます。


24. PCのウイルス除去


Norton Power Eraser
https://security.symantec.com/nbrt/npe.aspx?lcid=1041

説明

感染したPCからウイルスを除去する強力なツールです。
徹底的にデータを消すため、無害なソフトを巻き込むこともあるようです。
システムの復元でも消えない、hao123の除去も出来ます。


25. アプリケーション情報


Process Explorer
https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer

説明

不審な動きをするアプリケーションを特定するために使えます。


26. 広告除去


Adblock Plus
https://addons.mozilla.org/ja/firefox/addon/adblock-plus/

Element Hiding helper for Adblock Plus
https://addons.mozilla.org/ja/firefox/addon/elemhidehelper/

説明

インターネットのサイトに表示させる広告を除去することが出来ます。
スマホ(Android)用のAdblockブラウザもありますが、動作が遅いです。
firefox、Chromeにはプラグインがあります。

Adblock Plusは画像広告に強く、
Element Hiding helper for Adblock Plusはテキスト広告に強いです。
そのほかではublockが良いです。

また、スマホの広告除去を行いたい場合、
AndroidであればAdGuard(https://adguard.com/ja/welcome.html)
iphoneであれば280blocker(https://280blocker.net/)


27. 仮想環境


Vmware Player
https://www.vmware.com/products/player/playerpro-evaluation.html

説明

windows上にlinux環境を構築できます。
あくまでwindows上の仮想環境なので、linuxが壊れてしまった場合やlinuxを消したい場合も単にwindows上からフォルダを消すだけokです。


28. オフラインゲーム


Track Mania Forever
http://trackmaniaforever.com/
無料版ダウンロード http://www.4gamer.net/games/048/G004822/20080423014/

説明

オフラインで遊べるレーシングゲームです。
あるコースを時間内に走り抜けることが目的のゲームです。
コースエディタがあるので、自分で作ることが可能です。


29. SCP Containment Breach


SCP – Containment Breach
http://www.scpcbgame.com/index.html

説明

SCPがうごめく建物から脱出するゲームです。SCPを知っていると楽しめます。ねこ画像もいます。まずはSCP財団をご訪問下さい。


30. マウスオーバー英和辞書 -mouse dictionary


Mouse Dictionary

説明

chrome, firefoxのアドオンです。マウスオーバーにより、英単語の和訳が高速に表示されます。


31. 数式処理システム -Maxima


Maxima

説明

数式を数式のまま処理していくソフトです。wolfram alphaで出来るようなことがオフライン環境で、無料で出来るというイメージです。
微分とか積分とか、行列計算などが文字のまま計算が行われ、計算出来ます。

  • 計算ソフト -wolfram alpha
  • https://www.wolframalpha.com/
    高機能計算ソフトのwolfram alphaです。ある程度の積分、微分、微分方程式を解くことが出来ます。

  • グラフ描写 -gnuplot onlice
  • Gnuplot instantly
    gnuplotのウェブブラウザ版です。お手軽に使用でき、画像もダウンロード可能なので、非常に便利です。

  • latex記号検索 -detexify
  • detexify
    書きたい記号を手入力することで、latexのコマンドを教えてくれます。

  • グラフの数値化
  • WebPlotDigitizer
    グラフから値を読み取ることがウェブブラウザ上でできます。

  • 創作話 -SCP財団
  • SCP財団
    創作話です。常識に囚われない物体・概念・現象を創作して、話を繰り広げる短編集です。”SCP財団”は、そんな物体・概念・現象を確保・収容・保護するために世界の裏で活躍する目的を持った財団です。
    wiki形式なので、誰もがSCPを創作できます。ねこはいます。よろしくおねがいします。

    gnuplotで、あるディレクトリ内にある全てのファイルをプロットする

    まとめ


    gnuplotで、ディレクトリ(dat)内にある全てのファイルをプロットするには、

    fnames=system("/bin/ls ./dat/*")
    plot for[fn in fnames] sprintf("%s",fn) u 1:2

    とすればいいです。

    状況


    いま、ディレクトリの構造が

    .
    └── dat
        ├── a.d
        ├── b.d
        └── c.txt

    となっているとします。ここで、datはプロットしたいデータ(a.d、b.dとc.txt)が入っているディレクトリです。
    この時、gnuplot上で

    fnames=system("/bin/ls ./dat/*")
    plot for[fn in fnames] sprintf("%s",fn) u 1:2

    と入力すれば、ディレクトリdat内にある全てのファイルがプロットされます。

    また、拡張子.dにあてはまるものだけをプロットしたければ、

    fnames=system("/bin/ls ./dat/*.d")
    plot for[fn in fnames] sprintf("%s",fn) u 1:2

    とすればいいです。

    gnuplotで平均と分散を表示する

    gnuplotで平均、分散を表示します。
    このページのゴールは↑のアイキャッチ画像を得ることを目的にします。

    持ってるもの

    ・ファイル名”qwerty.d”に格納された1列目x、2列目y(x)のデータ。

    gnuplotを用いて出力するもの

    ・平均、分散の表示

    コマンド
    stats "qwerty.d" u 1:2 name "qw" nooutput

    plot "qwerty.d" u 1:2 pt 7 ps 1,\
          qw_mean_y lw 3 lt 1 lc 1 notitle,\
          qw_mean_y+qw_stddev_y lt 2 lc 1 notitle,\
          qw_mean_y-qw_stddev_y lt 2 lc 1 notitle

    とすれば以下の画像が得られます。

    真ん中の黒い実線が平均値、上下の黒の点線は平均値±標準偏差を表します。
    データが正規分布に従うのであれば、真値(この場合は平均値=真値を仮定)を中心に約68%が上下の点線内に入ります。

    水中下でのBB弾の弾道計算

    水中にBB弾が入った時の軌道は計算できるのでしょうか?
    もしも水中での軌道が分かったのならば、そこから回転量、初速が分かるはずです。

    まとめ


    目的

    • ハイスピードカメラを用いず、空気中で50mに及ぶ軌道を追わずに回転量を知ることが出来るか?
    • 弾道計算(BB弾)の理論の検証

    方法

    • 水槽に向けてエアガンを撃った軌道とBB弾の弾道計算理論による軌道と比較

    結論

    • 水中の軌道は定性的に一致
    • 定量的に合うのは到達距離、合わないのは水中での揚力
    • 水中の軌道から回転量を知るには理論的に不十分
    1. まとめ
    2. きっかけ
    3. 方針
      1. 理論上の問題
      2. 実験上の問題
    4. 実験と理論の比較
    5. 理論で回転の減衰を入れないと?
    6. 参考文献

    弾道計算に関するその他ページ
    弾道計算(BB弾)の理論
    BB弾の回転量について(実験との比較)
    弾道計算(BB弾)の結果
    弾道計算の結果2, 比較と詳細データ
    弾道計算(BB弾)のコード(fortran90)
    バレル内部でのBB弾の方程式
    水中下でのBB弾の弾道計算←今ここ

    [adsense1]

    きっかけ


    つい先日、こんな動画を見つけました。
    夏休み 自由研究? BB弾水に撃つと?検証してみた。 マック堺 エアガンレビュー

    水中の軌道じゃないですか。面白そう!
    計算できない理由は無い。
    式もある、プログラムもある。ならやってみよう。

    がきっかけです。何故計算しようと思ったか?素晴らしい理由はありません。そこに物理があるからです。

    方針


    厳密さはそこまで求めません。

    これには理由が2つあり、

    1. 水中を想定して作った理論ではないため、水の揺らぎが与える影響が不明。
    2. 実験がされた動画の縮尺、距離、回転量を見積もれない。

    だからです。詳しい理由は以下の通り。

    理論上の問題

    空気も水も同じ流体ですが、その特性は大きく違います。

    大気中の密度は低く、BB弾の密度と比べても0.1%未満です。そのため、大気の揺らぎがBB弾の影響することは無く、無視できるだろうと予想できます。
    しかし、水ではBB弾の半分程度の密度になるために無視はできません。これは、0.1gのBB弾が詰まった容器に0.2gのBB弾を打ち込むようなものです。なので、容器が揺らぐとBB弾もそれにつられて動きます。

    なので、現状のBB弾の弾道計算理論では考慮していない効果が現れるはずです。

    荒っぽいですが、水は全く揺らいでいないし、揺ぐこともないと考えましょう。
    この近似の下で、計算と実際の軌道が程度一致するのかを確かめていきます。

    実験上の問題

    実験の動画は軌道がはっきりわかるくらいのハイスピードカメラが使われています。
    しかし、動画の時間、位置スケールが分からない点と回転量が分からないため、大雑把な値しか見積もれません。
    せめて、同じ回転量で大気中の軌道があれば何とかなったかもしれませんが、無い以上は仕方ありません。

    よって、方針としては
    位置はBB弾のサイズから見積もり、
    時間の情報は軌道だけに注目することで無くし、
    回転量は数値計算する時の回転量を変えていって、重なる軌道があるかどうか?

    で考えで行きます。

    [adsense2]

    実験と理論の比較


    理論上の式を数値計算で解きます。数値計算で用いる数式は弾道計算(BB弾)の理論で導いた、空気抵抗、揚力、回転の減衰を考慮した運動方程式です。

    まず、マック堺様による実験動画[1]からサイズ、入射角などを見積もります。
    スクリーンショットをとって、BB弾の位置を等間隔に撮っていったのが下の画像になります。

    入射角の推定方法などは画像を見ていただければわかると思います。

    画像から
    入射角:51[度](→53[度]と推定)
    入射位置からの到達距離:18~22[cm]
    と分かりました。
    重さ、初速は動画上で0.20g, 90m/sと紹介されていたのでそれを用います。

    水中ではカーブするため、水中の2点間から導いた角度よりも大きくなることは確実です。
    53度という値は数値計算で得られた軌道から53度位が良さそうだ、という推定をしました。

    上記パラメータを利用し、
    水の密度を\(1000[\mbox{kg/m}^3]\),
    粘度を\(10^-3[\mbox{Pa}\cdot \mbox{s}]\)
    として回転量を変えていった時の軌道は以下のようになります。

    実験の状況から、横軸は拡大されて見えているはずなので、BB弾を打ち込んだ位置の到達距離は、推定した一番短い距離を利用しています。
    図中の赤い大きな点が実験のBB弾の位置で、線と点で表した4つの線が数値計算です。4つの黒、青、緑、紫は回転量の違いを表し、順に100、150、200、250回転/秒で計算した結果です。
    この回転数は妥当なものです。200回転の場合で大気中を想定し同じパラメータで計算しますと

    のようになり、ホップが効かな過ぎず効き過ぎずの妥当な軌道になっています。

    水の中を全く想定していない理論だとはいえ、良い結果だと思います。
    特に、到達距離が数値計算でも20cm前後であることが定量的に再現できたのは大きな成果だと思います。また、水中でも揚力によって上昇することが定性的に再現できました。
    揚力について、定量的に異なっています。実験では水面-最下点の半分以上上昇しているように見えますが、計算ではそこまで上昇しません。

    空気が入っていることが大きな原因だと思いますが、はっきりとはわかりません。
    先ほども述べた通り、水が揺らぐ効果は全く入っていないためです。
    もしかするとエアガンを水中に沈め、空気が入らない状態で発射すればよいと思いますが、エアガンが壊れるので現実的ではありません。

    銃口に膜でも作って、その膜を通してBB弾の衝撃をうまく伝わらせれば何とかなるかもしれませんが、今度は回転が無くなってしまいます。
    ホップのゴムパッキンのすぐ後ろに膜でも作れば何とか…?

    理論で回転の減衰を入れないと


    回転の減衰を入れないとどうなるでしょうか?
    大気中の場合はさほど重大な問題ではありませんでしたが、水中では以下のようになりました。200回転/秒で計算しています。

    回転の減衰を入れない計算は図中、水色の線であり、明らかに物理が破綻しています。
    回転の減衰を入れた計算は図中、緑色の線であり、直感と合い、良い振る舞いをしていることが分かります。

    参考文献


    [1]夏休み 自由研究? BB弾水に撃つと?検証してみた。 マック堺 エアガンレビュー
    このページでのみ、動画のスクリーンショットに変更を加えた画像の使用許諾済み。

    [2]水・空気の物性 密度 粘度 動粘度

    [3]弾道計算(BB弾)の理論 -シキノート

    離散フーリエ変換と畳み込みの計算

    こちらのページは後程消去いたします。

    以下のページに統合しますので、ご参照ください。
    https://slpr.sakura.ne.jp/qp/dft-for-numerical-calculation/

    本ページにはミスもあり、上の方が正しいですのでご参照ください。


    まとめ


    離散フーリエ変換(Discrete Fourier Transform,DFT)を
    \(
    \begin{eqnarray}
    \left\{
    \begin{aligned}
    f(\tilde{k}_n)&=\mathcal{F}[f(x)](\tilde{k}_n)=\sum_{m=0}^{N-1}f(x_m)e^{-i2\pi\tilde{k}_nx_m}\Delta x \\
    f(x_m)&=\mathcal{F}^{-1}[f(\tilde{k})](x_m)=\sum_{n=0}^{N-1}f(\tilde{k}_n)e^{i2\pi\tilde{k}_nx_m}\Delta \tilde{k}
    \end{aligned}
    \right.
    \end{eqnarray}
    \)

    と定義し、畳み込み(Convolution)を
    \(
    \displaystyle (f\ast g)(x_l)= \sum_{m} f(x_m) g(x_l-x_m) \Delta x
    \)

    と定義します。この時、畳み込みは上で定義した離散フーリエ変換を用いて以下の通り書けます。
    \(
    \displaystyle (f\ast g)(x_l)=\mathcal{F}^{-1}\left[\mathcal{F}[f(x)](\tilde{k})\cdot \mathcal{F}[g(x)](\tilde{k})\right](x_l)
    \)

    intel®マス・カーネル・ライブラリ(MKL)に実装されているフーリエ変換は
    \(
    \begin{eqnarray}
    \left\{
    \begin{aligned}
    (-1)^n f(\tilde{k}_n)&=\sum_{m=0}^{N-1}f(x_m)e^{-i2\pi nm/N} \\
    f(x_m)&=\sum_{n=0}^{N-1}(-1)^n f(\tilde{k}_n)e^{i2\pi nm/N}
    \end{aligned}
    \right.
    \end{eqnarray}
    \)

    の形で定義されています。ここで、\(f(\tilde{k}_n)\)は、正しいフーリエ変換後の関数。計算したもの。この時、上で定義されている場合、畳み込みは、
    \(
    \displaystyle (f\ast g)(x_m)=\frac{\Delta x}{N}\mathcal{F}_{MKL}^{-1}\left[\mathcal{F}_{MKL}[f(x)]\cdot\mathcal{F}_{MKL}[g(x)] (-1)^n\right](x_m)
    \)

    で計算できます。ここで、\(N\)は離散フーリエ変換に用いた分点数、\(n\)は順方向フーリエ変換後の空間を離散化した時のインデックスです。

    intel®MKLの離散フーリエ変換ルーチンを用いた畳み込みは、プログラムでは\(h(x)=(f\ast g)(x)\)とした時、

    \(
    \begin{align}
    & Status = DftiComputeForward(hand,f) \\
    & Status = DftiComputeForward(hand,g) \\
    & h(\tilde{k}_n)=z(\tilde{k}_n)\times g(\tilde{k}_n)\times (-1)^n ~~~~~(\mbox{for all } k_n) \\
    & Status = DftiComputebackward(hand,h) \\
    & h(x_m)=h(x_m)\times \frac{\Delta x}{N} ~~~~~(\mbox{for all } x_m)\\
    \end{align}
    \)

    とする必要があります。
    ※離散フーリエ変換はフーリエ変換の積分を短冊近似したものです。

    [adsense1]

    目次


    1. フーリエ変換の定義
    2. 離散フーリエ変換の定義
    3. たたみ込みの定義
    4. 離散たたみ込みと離散フーリエ変換
    5. 数値計算で使われている離散フーリエ変換アルゴリズム (例: intel®MKL)

    フーリエ変換の定義


    フーリエ変換の定義方法には複数の慣例があり、
    数値計算分野、化学、音の解析等においては
    \(
    \begin{align}
    f(\tilde{k})&=\int_{-\infty}^{\infty} f(x)e^{-i2\pi\tilde{k}x}dx \\
    f(x)&=\int_{-\infty}^{\infty} f(\tilde{k})e^{i2\pi\tilde{k}x}d\tilde{k}
    \end{align}
    \)

    の形で良く定義されます。
    ここで、例えば\(x\)は位置[m]であれば\(\tilde{k}\)は波数[1/m]です。
    また、\(x\)が時間[s]であれば\(\tilde{k}\)は周波数[1/s]です。

    このページでは扱いませんが、物理科学の世界では
    \(
    \begin{align}
    f(k)&=\int_{-\infty}^{\infty} f(x)e^{-ikx}dx \\
    f(x)&=\int_{-\infty}^{\infty} f(k)e^{ikx}\frac{dk}{2\pi}
    \end{align}
    \)

    の形で良く定義されます。
    ここで、例えば\(x\)は位置[m]であれば\(k\)は角波数[1/m]です。
    また、\(x\)が時間[s]であれば\(k\)は角周波数[1/s]です。

    この2つの違いは周波数か、角周波数のどちらが本質であるか?という事だと思います。
    物理では、周波数よりも角周波数の方が式が簡便になります。
    ですが、人間の理解がしやすいのは1秒当たり何回振動するか?という周波数だろう、と思うため工学よりの分野では周波数が使われるのでしょう。もしかしたら、単に慣例だけかもしれません。

    どちらも定数倍の変数変換の違いだけなので、本質は変わりません。
    数値計算依りの話をしていきたいので、ここからは前者の位置⇔波数で考えていきます。

    また、

    順方向フーリエ変換:\(e^{-i2\pi\tilde{k}x}\)の因子が掛かっている式、空間→波数
    逆方向フーリエ変換:\(e^{+i2\pi\tilde{k}x}\)の因子が掛かっている式、波数→空間

    と呼び、
    ”関数\(f(x)\)の順方向フーリエ変換して波数\(\tilde{k}\)の空間に移る”
    という操作を華文字\(\mathcal{F}\)を用いて
    \(
    \mathcal{F}[f(x)](\tilde{k})
    \)

    と表します。また、
    ”関数\(f(k)\)の逆方向フーリエ変換して位置\(x\)の空間に移る”
    という操作を
    \(
    \mathcal{F}^{-1}[f(\tilde{k})](x)
    \)

    と表します。

    離散フーリエ変換の定義


    このページでは離散フーリエ変換を
    \(
    \begin{align}
    f(\tilde{k}_n)&=\sum_{m=0}^{N-1}f(x_m)e^{-i2\pi\tilde{k}_nx_m}\Delta x \\
    f(x_m)&=\sum_{n=0}^{N-1}f(\tilde{k}_n)e^{i2\pi\tilde{k}_nx_m}\Delta \tilde{k}
    \end{align}
    \)

    定義します
    \(\Delta x\), \(\Delta \tilde{k}\)は、それぞれ位置、波数空間の刻み幅を表します。

    この上の定義は簡便さのために良く使われる
    \(
    \begin{align}
    f(\tilde{k}_n)&=\frac{1}{N}\sum_{m=0}^{N-1}f(x_m)e^{-i2\pi\tilde{k}_nx_m} \\
    f(x_m)&=\hspace{1.5em}\sum_{n=0}^{N-1}f(\tilde{k}_n)e^{i2\pi\tilde{k}_nx_m}
    \end{align}
    \)

    という定義と同一です。
    ただし、これは積分をそのまま離散化したものではないため、積分の意味は薄れてしまいます。
    その結果、畳み込みなど、フーリエ変換後同士の物を掛け算する時は違った結果になってしまいます。
    このページではこの簡便さの為の離散フーリエ変換は使いません。

    上の2つの定義が同じ理由は、順方向→逆方向を行い、元に戻った時に係数が\(\Delta x\Delta \tilde{k}=\frac{1}{N}\)になるためです。

    \(x_m\) \(\tilde{k}_n\)
    添え字 \(m=0,1,2,\cdots,N-1\) \(n=0,1,2,\cdots,N-1\)
    区間 \(\displaystyle [a,b]\) \(\displaystyle \left[-\frac{1}{2\Delta x},\frac{1}{2\Delta x}\right]\)
    刻み幅 \(\displaystyle \Delta x=\frac{b-a}{N}\) \(\displaystyle \Delta \tilde{k}=\frac{1}{b-a}\)
    分点の位置 \(\displaystyle x_m=m\Delta x +a\) \(\displaystyle \tilde{k}_n=n\Delta \tilde{k} -\frac{1}{2\Delta x}\)

    ただし、\(x_m, \tilde{k}_n\)は以下の関係式を見たします。
    \(
    \begin{align}
    & x_m+N\Delta x=x_m\\
    & \tilde{k}_n+N\Delta \tilde{k}=\tilde{k}_n
    \end{align}
    \)

    ナイキスト(Nyquist)周波数について


    ナイキスト周波数とはサンプリングする間隔でどの周波数を持つ関数までを表現できるか?という下限と上限を与えます。
    今回の場合、上の表の通り\(\tilde{k}\)空間で表現できる上限と下限は\(\pm\frac{1}{2\Delta x}\)です。この絶対値、すなわち\(\frac{1}{2\Delta x}\)をナイキスト周波数と呼びます。

    ナイキスト周波数が意味しているのは、高周波の成分を取り出したければサンプリングする間隔を小さくしなければならない。ということです。”サンプリングの間隔”は周波数と同じ意味ですので、サンプルする周波数を高くしなければならない。と言い換えることもできます。

    具体例を上げましょう。

    上の図は関数\(\displaystyle f(x)=e^{i2\pi \tilde{k}x}\)をサンプル間隔\(\Delta x = 0.5\)で離散的な関数で表現したものです。
    この場合、ナイキスト周波数は\(\frac{1}{2\times 0.5}\)より、\(1\)です。
    すなわち、このサンプル間隔では\(\tilde{k}\)が\([-1,1]\)の範囲を持つものしか表現することが出来ません。
    では、実際にサンプル出来ない関数\(\displaystyle f(x)=e^{i2\pi 1.8 x},~~(\tilde{k}=1.8)\)を考えた時に何が起こるのでしょうか。
    それを示したのが下から2番目の関数です。
    本来は早く振動する関数であるのに、あたかも非常にゆっくりとした関数だ、と捉えられてしまいます。しかも位相が反転しています。

    これは、元々は\(e^{i\theta}\)の周期性によるものです。簡単な計算の通り、
    \(
    \begin{align}
    e^{i(\theta+2\pi)}=e^{i\theta}e^{i2\pi}=e^{i\theta}
    \end{align}
    \)

    となります。この周期性のために、\(\tilde{k}:[-1,1]\)の範囲でしか表現できない空間で、
    その範囲外の\(\tilde{k}\)を表現しようとした時には、\(\tilde{k}\)空間の大きさ(…この場合は\(2\))を足したり引いたりして\(\tilde{k}:[-1,1]\)の範囲に強制的に押し込まれます。
    \(\tilde{k}=1.8\)の場合は、\(\tilde{k}=1.8-2=-0.2\)となります。
    言葉で言えば、
    \(\tilde{k}=1.8\)を持つ波形は\(\tilde{k}=-0.2\)を持つ波形としてとして表現される
    ということです。

    本来の関数を薄く描いて重ねたものが以下のものになります。

    フーリエ変換が元に戻ることの証明


    上記のフーリエ変換、離散フーリエ変換はある制限を課しています。
    それは、
    ある関数に順方向フーリエ変換を行い、続いて逆方向フーリエ変換を施した場合、元と同じ関数に戻っていて欲しい。
    という要望です。
    それは、以下のように証明できます。

    フーリエ変換
    \(
    \begin{align}
    f(x)&=\int_{-\infty}^{\infty}d\tilde{k} f(\tilde{k})e^{i2\pi\tilde{k}x} \\
    &=\int_{-\infty}^{\infty}d\tilde{k} \left[\int_{-\infty}^{\infty}dx’ f(x’)e^{-i2\pi\tilde{k}x’}\right]e^{i2\pi\tilde{k}x} \\
    &=\int_{-\infty}^{\infty}dx’ f(x’)\int_{-\infty}^{\infty}d\tilde{k}
    e^{i2\pi\tilde{k}(x-x’)} \\
    &=\int_{-\infty}^{\infty}dx’ f(x’)\delta(x-x’) \\
    &=f(x)
    \end{align}
    \)

    離散フーリエ変換

    \(
    \begin{align}
    f(x_m)&=\sum_{n=0}^{N-1}f(\tilde{k}_n)e^{i2\pi\tilde{k}_nx_m}\Delta \tilde{k}\\
    &=\sum_{n=0}^{N-1}\left[\sum_{m’=0}^{N-1}f(x_{m’})e^{-i2\pi\tilde{k}_nx_{m’}}\Delta x\right]e^{i2\pi\tilde{k}_nx_m}\Delta \tilde{k} \\
    &=\Delta \tilde{k}\Delta x\sum_{m’=0}^{N-1}f(x_{m’})\sum_{n=0}^{N-1}e^{i2\pi\tilde{k}_n(x_m’-x_m)} \\
    &=\frac{1}{N}\sum_{m’=0}^{N-1}f(x_{m’})\sum_{n=0}^{N-1}e^{i2\pi n (m’-m)/N +i2\pi(\theta_{m}-\theta_{m’})} \\
    &=\frac{1}{N}\sum_{m’=0}^{N-1}f(x_{m’})e^{i2\pi(\theta_{m}-\theta_{m’})}N\delta_{m,m’} \\
    &=f(x_m)
    \end{align}
    \)
    ここで、
    \(
    \begin{align}
    \tilde{k}_n x_{m}=\frac{nm}{N}+\frac{an}{N\Delta x}+\theta_{m} \\
    \theta_{m}=-\frac{a}{2\Delta x}-\frac{m}{2}
    \end{align}
    \)

    そして、等比級数の考えから、
    \(
    \begin{eqnarray}
    \sum_{n=0}^{N-1}e^{i2\pi n a}=
    \left\{
    \begin{aligned}
    &\frac{e^{i2\pi aN}-1}{e^{i2\pi a}-1}, \hspace{1em} ( a\ne 0) \\
    & N, \hspace{4em} (a=0) \\
    \end{aligned}
    \right.
    \end{eqnarray}
    \)

    という関係式を用いました。

    畳み込み(convolution)の定義


    このページでは、畳み込みを
    \(
    \displaystyle (f\ast g)(x)=\int f(\tau) g(x-\tau) d\tau
    \)

    という積分であると定義し、離散的な畳み込みを
    \(
    \displaystyle (f\ast g)(x_l)= \sum_{m} f(x_m) g(x_l-x_m) \Delta x
    \)

    定義します。

    畳み込みの定義には\(\Delta x\)が掛けられていないものが存在しますが、積分の意味が薄れてしまうため、離散フーリエ変換時と同様、このページでは\(\Delta x\)を掛けたものを畳み込み、と定義します。

    区間\([a,b]\)で定義された離散的な畳み込みの場合、関数\(f(x),g(x)\)は区間が\([a,b]\)で決められている場合がほとんどです。
    この場合、引数\(x_m-x_l\)が定義域内に収まらない場合が現れます。

    定義域からはみ出てしまった場合は推定するしかありません。
    推定の仕方によって
    循環畳み込みと呼ばれる方法と直線畳み込みと呼ばれる方法が良くつかわれています。

    循環畳み込みは領域に対して周期境界条件を課したもの、すなわち、上限bと下限aが繋がっていると考えます。
    直線畳み込みは領域に対して固定端条件を課したもの、すなわち、[a,b]の範囲外の関数値はゼロと考えます。

    問題に大きく依るので、どちらがいいかはありません。

    離散畳み込みと離散フーリエ変換


    離散畳み込みは定義通り
    \(
    \displaystyle (f\ast g)(x_l)= \sum_{m} f(x_m) g(x_l-x_m) \Delta x
    \)

    で計算することが出来ます。計算量は\(O(n^2)\)です。

    しかし、実用上は離散フーリエ変換を利用すると計算量を\(O(n\log n)\)に抑えられます。
    計算方法はたたみ込み定理を利用して、
    \(
    \displaystyle \mathcal{F}[(f\ast g)(x)](k)=\mathcal{F}[f(x)](k)\cdot \mathcal{F}[g(x)](k)
    \)

    より、\((f\ast g)(x)\)は
    \(
    \displaystyle (f\ast g)(x)=\mathcal{F}^{-1}\left[\mathcal{F}[f(x)](k)\cdot \mathcal{F}[g(x)](k)\right]
    \)

    と書けるため、フーリエ変換を介することで計算量を減らせます。
    離散フーリエ変換を介して畳み込みを計算する場合、必ず循環畳み込みで計算することになります。

    畳み込み定理の証明

    連続畳み込み

    \(
    \displaystyle \mathcal{F}[(f\ast g)(x)](k)=\mathcal{F}[f(x)](k)\cdot \mathcal{F}[g(x)](k)
    \)

    左辺)
    \(
    \begin{align}
    \mathcal{F}[(f\ast g)(x)](\tilde{k})
    &=\int \left[\int f(\tau)g(x-\tau) d\tau\right] e^{-i2\pi \tilde{k} x} dx \\
    & x-\tau=y\mbox{の変数変換を行って} \nonumber \\
    &=\int dy\int d\tau f(\tau)g(y) e^{-i2\pi \tilde{k} (\tau+y)} \\
    &=\int dx\int dx’ f(x)g(x’) e^{-i2\pi \tilde{k} (x+x’)}
    \end{align}
    \)

    右辺)
    \(
    \begin{align}
    \mathcal{F}[f(x)](\tilde{k})\cdot \mathcal{F}[g(x)](\tilde{k})
    &=\int f(x) e^{-i2\pi \tilde{k} x} dx \cdot \int g(x’) e^{-i2\pi \tilde{k} x’} dx’ \\
    &=\int dx\int dx’ f(x)g(x’) e^{-i2\pi \tilde{k} (x+x’)}
    \end{align}
    \)

    より、証明終了。また、逆変換により戻ることを示します。
    \(
    \begin{align}
    &\mathcal{F}^{-1}\left[\mathcal{F}[f(x)](\tilde{k})\cdot \mathcal{F}[g(x)](\tilde{k})\right] \\
    &=\int \left[\int dx\int dx’ f(x)g(x’) e^{-i2\pi \tilde{k} (x+x’)}\right] e^{i2\pi \tilde{k} y} dk\\
    &=\int dx\int dx’ f(x)g(x’) \int e^{-i2\pi \tilde{k} (x+x’-y)} dk\\
    &=\int dx\int dx’ f(x)g(x’) \delta(x’-(y-x)) \\
    &=\int dx f(x)g(y-x) \\
    &=\int d\tau f(\tau)g(x-\tau) \\
    \end{align}
    \)
    となり、フーリエ変換を介してたたみ込みが計算できることが示せました。

    離散畳み込み

    \(
    \displaystyle \mathcal{F}[(f\ast g)](\tilde{k})=\mathcal{F}[f(x)](\tilde{k})\cdot \mathcal{F}[g(x)](\tilde{k})
    \)

    左辺)
    \(
    \begin{align}
    \mathcal{F}[(f\ast g)(x)](\tilde{k}_n)
    &=\mathcal{F}\left[\sum_{m=0}^{N-1}f(x_m)g(x-x_m)\Delta x\right] \\
    &=\sum_{l=0}^{N-1}\left[\sum_{m=0}^{N-1}f(x_m)g(x_l-x_m)\Delta x\right]e^{i2\pi \tilde{k}_n x_l}\Delta x \\
    &=(\Delta x)^2\sum_{l=0}^{N-1}\sum_{m=0}^{N-1}f(x_m)g(x_l-x_m) e^{i2\pi \tilde{k}_n x_l} \\
    &\mbox{ここで、循環たたみ込みを想定し、}x_l-x_m=x_{m’}\mbox{となるように}x_{m’}\mbox{を決めると}\nonumber \\
    &=(\Delta x)^2\sum_{m=0}^{N-1}\sum_{m’=0}^{N-1}f(x_m)g(x_{m’}) e^{i2\pi \tilde{k}_n (x_m+x_{m’})} \\
    \end{align}
    \)

    右辺)
    \(
    \begin{align}
    \mathcal{F}[(f(x)](k_n)\cdot \mathcal{F}[(g(x)](k_n)
    &=\sum_{m=0}^{N-1}f(x_m) e^{i2\pi \tilde{k}_n (x_m)}\Delta x\cdot \sum_{m’=0}^{N-1}f(x_{m’}) e^{i2\pi \tilde{k}_n (x_{m’})}\Delta x \\
    &=(\Delta x)^2\sum_{m=0}^{N-1}\sum_{m’=0}^{N-1}f(x_m)g(x_{m’}) e^{i2\pi \tilde{k}_n (x_m+x_{m’})}
    \end{align}
    \)
    よって右辺と左辺が正しくなります。

    逆変換によって離散畳み込みになることを示します。

    \(
    \begin{align}
    \mathcal{F}^{-1}[\mathcal{F}[(f\ast g)(x)](k)](x_l)
    &=\mathcal{F}^{-1}\left[(\Delta x)^2\sum_{m=0}^{N-1}\sum_{m’=0}^{N-1}f(x_m)g(x_{m’}) e^{i2\pi \tilde{k}_n (x_m+x_{m’})}\right]\\
    &=\sum_{n=0}^{N-1}\left[(\Delta x)^2\sum_{m=0}^{N-1}\sum_{m’=0}^{N-1}f(x_m)g(x_{m’}) e^{i2\pi \tilde{k}_n (x_m+x_{m’})}\right]e^{-i2\pi \tilde{k}_n x_l}\Delta \tilde{k}\\
    &=(\Delta x)^2 \Delta \tilde{k} \sum_{m=0}^{N-1}\sum_{m’=0}^{N-1} f(x_m)g(x_{m’})\sum_{n=0}^{N-1}e^{i2\pi \tilde{k}_n (x_m+x_{m’}-x_l)} \\
    &=\frac{\Delta x}{N} \sum_{m=0}^{N-1}\sum_{m’=0}^{N-1} f(x_m)g(x_{m’})N\delta_{x_{m’},x_l-x_m} \\
    &=\sum_{m=0}^{N-1}f(x_m)g(x_l-x_m)\Delta x \\
    &=(f\ast g)(x_l)
    \end{align}
    \)

    よって畳み込みの定理通りに戻るため、離散フーリエ変換を介して畳み込みの計算ができます。

    ※注意
    \(\Delta x, \Delta \tilde{k}\)が掛けられていない方の離散フーリエ変換と畳み込みでは元に戻りません。畳み込みの計算時に係数倍違って出てきます。

    数値計算で使われている離散フーリエ変換アルゴリズム (例: intel®MKL)


    数値計算では、上記の離散フーリエ変換の形、指数の肩に\(\tilde{k},x\)を含む物はあまり使われません。
    そして、数値計算上での離散フーリエ変換の定義方法は複数存在します。
    マニュアルを見てください。

    ここでは、intel®マス・カーネル・ライブラリ(MKL)に使われている離散フーリエ変換アルゴリズムについて言及します。

    MKLの変換はどうやら
    \(
    \begin{align}
    (-1)^n f(\tilde{k}_n)&=\sum_{m=0}^{N-1}f(x_m)e^{-i2\pi nm/N} \\
    f(x_m)&=\sum_{m=0}^{N-1}(-1)^n f(\tilde{k}_n)e^{i2\pi nm/N}
    \end{align}
    \)

    という定義に従い変換しているようです。規格化因子\(\frac{1}{N}\)はユーザー任せです。
    ここで、
    \(f(\tilde{k}_n)\)は本来のフーリエ変換後の関数、
    \(f(x)\)は\(x\)空間での関数
    を表します。

    ”しているようです”と書いたのは、マニュアルと異なっているからです。マニュアルでは\((-1)^n\)など存在しませんが、実際試してみると、こういう変換をしているからです。

    MKLではどういう\(\tilde{k}\)を想定しているかを考えたところ、以下の状況のようです。

    \(x_m\) \(\tilde{k}_n\)
    添え字 \(m=0,1,2,\cdots,N-1\) \(n=0,1,2,\cdots,N-1\)
    区間 \(\displaystyle [-a,a]\) \(\displaystyle \left[0,N\Delta \tilde{k}\right]\)
    刻み幅 \(\displaystyle \Delta x=\frac{2a}{N}\) \(\displaystyle \Delta \tilde{k}=\frac{1}{2a}\)
    分点の位置 \(
    \begin{eqnarray}
    x_m=\left\{
    \begin{aligned}
    & m\Delta x ~~~~(m=0,\cdots,\frac{N}{2}-1) \\
    & m\Delta x-\frac{1}{\Delta \tilde{k}} (m=\frac{N}{2},\cdots,N-1)
    \end{aligned}
    \right.
    \end{eqnarray}
    \)
    \(\displaystyle \tilde{k}_n=n\Delta \tilde{k} ~~~~(n=0,\cdots,N-1)\)

    ただし、\(x_m, \tilde{k}_n\)は以下の周期境界条件を見たします。
    \(
    \begin{align}
    & x_m+N\Delta x=x_m\\
    & \tilde{k}_n+N\Delta \tilde{k}=\tilde{k}_n
    \end{align}
    \)

    区間[-a,a]で定義された\(x_m\)の順番がおかしく感じますが、これは周期境界条件を用いて、
    区間[0,2a]で定義された\(x_m=m\Delta x ~~~~(m=0,\cdots,N-1)\)
    と見ても良いです。
    なので、実用上どうやって関数\(f(x)\)を入れればよいか?に困ることは無いでしょう。
    この上記離散フーリエ変換を考えると、上で提示したMKLの離散フーリエ変換が導くことが出来、プログラム上でも一致します。

    MKLの離散フーリエ変換の導出)

    離散フーリエ変換時の注意点

    上に記した、余分な係数\((-1)^n\)のためにMKLを利用して求められた離散フーリエ変換の値は、本来のフーリエ変換後の関数と異なります。
    具体的に例を示しましょう。

    \(e^{-\alpha x^2}\)のフーリエ変換は
    \(
    \displaystyle \int_{-\infty}^{\infty} e^{-\alpha x^2}e^{-i2\pi\tilde{k} x}dx=\sqrt{\frac{\pi}{\alpha}}e^{-\pi^2\tilde{k}^2/\alpha}
    \)

    です。離散フーリエ変換を定義通り計算したものと、MKLを用いて離散フーリエ変換すると以下のようになります。
    左から\(f(x), \mathcal{F}[f(x)](\tilde{k}),\mathcal{F}^{-1}[\mathcal{F}[f(x)]](x)\)になっています。

    ここで、因子\((-1)^n\)のために交互に符号が変わっていることが分かるでしょう。
    後でやりますが、このせいで畳み込みの計算をする際には気を付けなければなりません。

    計算コードはこちら。

    MKLのルーチンは優秀です。誤差が余りたまらないようです。
    定義通り、愚直に作ったプログラムでは計算速度が遅いだけでなく、計算精度も悪くなります。
    下の画像は、離散フーリエ変換→逆変換を複数回繰り返した時、元の関数とどれだけずれるかを表しています。

    定義通りの離散フーリエ変換を\(10^n\)回繰り返すと\(n\)に対し線形にあがっていきます。この誤差は丸め誤差に起因しているのだと思います。しかし、MKLのルーチンには起こっていません。どういうアルゴリズムか知りませんが、優秀なのでしょう。

    [adsense2]

    フーリエ変換を介する畳み込み時の注意点

    MKLの離散フーリエ変換ルーチンを使って畳み込みを計算します。
    例として、以下の関数を考えましょう。
    \(
    \begin{align}
    h(x)&=\int \tau^5 e^{-\tau^2}\cdot e^{-4(x-\tau)^2}d\tau \\
    &=\frac{1}{3125}\sqrt{\frac{\pi}{5}}x(1024x^4+1600x^2+375)e^{-\frac{4}{5}x^2}
    \end{align}
    \)

    ここで、
    \(
    \begin{align}
    f(\tau)=\tau^5 e^{-\tau^2}
    g(\tau)=e^{-4\tau^2}
    \end{align}
    \)
    です。

    このページで紹介した定義の畳み込みでは証明した通り、
    \(
    h(x_m)=\mathcal{F}^{-1}\left[\mathcal{F}[f(x)](\tilde{k})\cdot\mathcal{F}[g(x)](\tilde{k})\right](x_m)
    \)

    で計算できます。
    しかし、MKLの離散フーリエ変換(\(\mbox{DFT}_{MKL}\))の場合は簡単にはできません。計算は、
    \(
    \displaystyle (f\ast g)(x_m)=\frac{\Delta x}{N}\mathcal{F}_{MKL}^{-1}[\mathcal{F}_{MKL}[f(x)]\cdot\mathcal{F}_{MKL}[g(x)] (-1)^n](x_m)
    \)

    としなければなりません。\((-1)^n\)は順方向フーリエ変換が2回あり、MKLの逆方向離散フーリエ変換に必要なこの係数が落ちてしまうため入れなければなりません。また、MKLのルーチンでは係数\(\Delta x, \Delta\tilde{k}\)を含んでいないので計算しておく必要があります。

    intel®MKLを用いる際、
    順方向離散フーリエ変換にはDftiComputeForward、
    逆方向離散フーリエ変換にはDftiComputeBackward
    を使うと、擬コードはこのように書けるかと思います。

    \(
    \begin{align}
    & Status = DftiComputeForward(hand,f) \\
    & Status = DftiComputeForward(hand,g) \\
    & h(\tilde{k}_n)=z(\tilde{k}_n)\times g(\tilde{k}_n)\times (-1)^n ~~~~~(\mbox{for all } k_n) \\
    & Status = DftiComputebackward(hand,h) \\
    & h(x_m)=h(x_m)\times \frac{\Delta x}{N} ~~~~~(\mbox{for all } x_m)\\
    \end{align}
    \)

    \(\displaystyle \Delta x \Delta\tilde{k}=\frac{1}{N}\)の関係を用いて最後にまとめて定数倍しています。

    上の計算方法に従うと正しく畳み込みが計算出来ます。
    実際にやってみますと、

    という結果を得ます。

    畳み込みを計算するコードはこちら

    モスクワの地下鉄と電車

    モスクワ周辺には2種類の電車があります。

    一つは “メトロ” と呼ばれる地下鉄、もう一つは “electric train”と呼ばれるモスクワ中心から放射状に延びる電車です。

    メトロ
    ・料金は距離に依らない。
    ・時刻表は無い

    メトロ内にいる限り、乗り換えても、どこまで行っても1回50ルーブル。
    時刻表が無いのは1~5分程度待っていれば次の電車が来るためです。
    また、回数券が存在し、例えば20回分で630rubなど安くなります。が、窓口のみ。
    1人が20回分買って、その券を別の人の券として使うのもありです。
    入場のみに券が必要で、出るときには必要ありません。

    メトロの地図は
    https://metro.yandex.com/moscow
    がお勧めです。yandexはロシアで主要な検索サイトです。
    英語版ももちろんあります。
    また、Google playにおいて、
    Яндекс.Метро
    というアプリがあるので、入れておくと良いでしょう。

    electric train
    ・料金は距離に依存する
    ・降りる駅に駅員がいない事も。
    ・切符を持っていないと400rub前後の罰則金あり

    料金システムは日本と同じです。移動する区間に応じて値段が変わります。
    困るのが切符の購入です。
    自動券売機があれば英語表記の案内がありますので楽に買えますが、小さい駅に自動券売機はありません
    この場合、どちらかの方面行き(もしくは両面)に存在する窓口で直接話して買わなければなりません。
    英語はほぼ通じません。
    紙に行先の駅を書いて、見せるのがいいでしょう。

    ちなみに切符を買わなくても電車には乗れます。しかし、定期的に警備員が電車内を巡回しており、切符を見せろ、と行ってきます。もしもチケットが無かった場合罰則金を取られるそうです。
    (駅のホームの端から改札を通過せずに降りたり、登ったりする現地の人を見ますが、つまりそういう事です。)

    Google playでは、
    Яндекс.Электрички
    があるので入れておくといいと思います。

    ※日本から試すならば、インストールした後に地域設定をしなくてはなりません。
    モスクワに行くならば、
    歯車のマーク→Пригородная зонаの項目をМосковскаяにしてください。現地に行き現在地情報を使えば自動的に設定されるはずです。

    Clenshaw–Curtis求積法

    クレンショウ-カーティス(Clenshaw–Curtis)型の数値積分公式です。

    [2]の論文”IS GAUSS QUADRATURE BETTER THAN CLENSHAW–CURTIS?”の結論だけかいつまみますと、

    ・クレンショウ-カーティスの求積法は、基本的にはガウス-ルジャンドル求積法と同じ性能
    ・クレンショウ-カーティスの求積法は実装が簡単

    ということです。
    本気で計算精度を求めようとするならばガウス-ルジャンドル求積法、簡単に、でもかなりの精度で求めたければクレンショウ-カーティスの求積法なのだと思います。
    ガウス-ルジャンドル求積法は分点の位置と重みの計算が簡単ではないのです。

    積分
    \(
    \displaystyle \int_{-1}^1 f(x) dx \sim \sum_{k=0}^{n} \omega_k f(x_k)
    \)

    Nが偶数の時、分点\(x_k\)と重み\(\omega_k\)は
    \(
    \displaystyle x_k=\cos\left(\frac{k\pi}{N}\right),\;\;\;k=0,1,\cdots,N
    \)

    \(
    \begin{align}
    \omega_0 &=\omega_N =\frac{1}{N^2 -1} \\
    \omega_s &=\omega_{N-s} = \frac{4}{n^2}\sum^{n/2}_{j=0}{\prime\prime }\frac{1}{1-4j^2}\cos\left(\frac{2j\pi s}{n}\right),\;\;\;s=0,1,\cdots,\frac{N}{2}
    \end{align}
    \)

    ここで、\(\sum{\prime\prime }\)は和の最初と最後の項に\(\frac{1}{2}\)を乗じることを意味します。

    N点の分点に対し、誤差のオーダーは\(O(N+1)\)です。
    \(x_k\)はチェビシェフ多項式\(T_n(x)\)の極値点になっています。

    利点


    ・重みの計算に掛かる時間が\(O(N log N)\).
    ・2N点での積分値を求める際にN点で計算した評価点を用いることが出来る。

    ガウス求積法と比べて


    ・ガウス型の重みの計算に掛かる時間は\(O(N^2)\).ただし、分点と重みは一度求めてしまえばずっと使いまわせるので、さほど重要な問題ではありません。
    ・ガウス-ルジャンドル求積法の分点を\(N\)点利用し、それに\(N\)点追加することでガウス-クロンロッド求積法が使えます。ガウス-ルジャンドルはN点の求積で\(O(x^{2N})\)、ガウス-クロンロッドは2N点の求積で\(O(x^{3N})\)の多項式まで正確に表すことが出来ます。

    結論

    本気で計算精度が欲しいならばガウス-ルジャンドル求積法。
    簡単に、でもかなりの精度で求めたければクレンショウ-カーティスの求積法なのだと思います。

    プログラム


    最適化は特にしていませんが、fortran90ではこんな感じになります。

    program main
      implicit none
      integer::i,j,N
      double precision::a,b,s
      double precision,allocatable::x(:),w(:)
      double precision,parameter::pi=acos(-1d0)
      double precision::f
      external::f
     
      a=0d0
      b=pi
       
      N=11
      allocate(x(1:N),w(1:N))
      call clenshaw_curtis_xw(N,x,w)
      w=w*(b-a)*0.5d0
      x=(x*(b-a)+(b+a))*0.5d0

      s=0d0
      do i=1,N
         s=s+f(x(i))*w(i)
      enddo
      write(6,*)s

      stop
    end program main
       
    function f(x)
      implicit none
      double precision::f,x
      double precision::pi=dacos(-1d0)
     
      f=sin(x)*x
     
      return
    end function

    subroutine clenshaw_curtis_xw(N,x,w)
      implicit none
      integer,intent(in)::N
      double precision,intent(out)::x(1:*),w(1:*)
      double precision,parameter::pi=3.14159265358979323846264338327950288d0
      integer::i,j,M,k
      double precision::c
     
      if(mod(N,2).eq.0)then
         write(6,*)"N must be odd"
         stop
      endif
     
      M=N-1
     
      do i=0,M
         x(i+1)=cos(i*pi/dble(M))
      enddo
      w(1)=1d0/((M-1d0)*(M+1d0))
      w(M+1)=w(1)

      do i=1,M/2
         k=i+1
         w(k)=0.5d0*(1d0+cos(pi*i)/((1d0-M)*(1d0+M)))
         c=2d0*pi*i/M
         do j=1,M/2-1
            w(k)=w(k)+cos(c*j)/((1d0-2d0*j)*(1d0+2d0*j))
         enddo
         w(k)=w(k)*4d0/M
         
         w(M-i+1)=w(k)
      enddo

      return
    end subroutine clenshaw_curtis_xw

    参考文献

    [1]P. J. Davis, P. Rabinowitz著、森正武訳 『計算機による数値積分法』p. 131-132,初版 (1980)
    [2]LLOYD N. TREFETHEN, IS GAUSS QUADRATURE BETTER THAN CLENSHAW–CURTIS?

    奥多摩探索(工場と廃墟への行き方)

    奥多摩は東京にありながら自然豊かです。

    ここでは、奥多摩にある工場(奥多摩工業㈱)と廃墟(奥多摩湖ロープウェイ、みとうさんぐち駅)への道順を記述していきます。

    奥多摩工業㈱ 氷川工場

    概要


    奥多摩工業㈱ 氷川工場は石灰の採掘、販売を行う稼働中の工場です。
    稼働中なのですが、一部壁が剥がれ落ちていたり、増築に増築を重ねたようなSFを漂わす感じが非常に魅力です。
    (奥多摩工業 -wikipedia)

    場所



    綺麗に見える場所は日原川から望む展望でしょう。
    上の地図上の、緑色の場所から望めます。
    こんな感じ

    工場脇を流れる日原川は澄み切っています。

    また、工場の内部に立ち入ることはできませんが、工場を横切るように一般道が存在しています。
    この一般道は地図上の赤いポイントから赤いポイントです。

    上流から望む氷川工場の写真がwikipediaにありました。この場所は工場のすぐ上にある釣り堀から撮ったと思われます。

    untitled

    [adsense1]

    奥多摩湖ロープウェイ、みとうさんぐち駅

    概要


    奥多摩湖ロープウェイは小河内観光開発株式会社が運行を行っていましたが、1975年に正式に運行休止され、現在では事実上の廃墟になっています。
    ロープウェイ自体は1962年-1966年まで操業されていました。
    現在、地元自治体の申し出によって立ち入りは禁止されているようです(wikipedia情報 小河内観光開発)。

    50年近く経った現在でもコンクリート作りの建物であるため、しっかりと残っています。

    場所


    場所は奥多摩周遊道路、川野駐車場のすぐ横の階段を昇った先にあります。

    (2017年5月確認)日祝の場合
    ・バス停「奥多摩駅」発 → バス停「陣屋」(じんや)降車(乗車時間30分)
    発車時刻 2番バスターミナル、奥12 (7:25、10:05、13:35、16:35)
      コ : 留浦経由小菅の湯行 奥12
      小 : 大菩薩峠東口経由小菅の湯行 奥12
      奥多摩駅、バス時刻表 http://transfer.navitime.biz/bus-navi/pc/diagram/BusDiagram?orvCode=00042103&course=0000431622&stopNo=1

    ・バス停「陣屋」発 → 奥多摩駅行き(乗車時間30分)
    発車時刻 奥12(8:56、11:46、15:07、18:07)

    陣屋、バス時刻表http://bus.ekitan.com/rosen/Rp700?t=0&b=310615&f=0&b2=310558&com=31&cn=%90%BC%93%8C%8B%9E%83o%83X

    ※後から気が付きましたが、バスは1区間遠い『深山橋』で降りる/乗ると奥12だけでなく、奥09,奥10,奥11でも良いようです。この場合、一時間に一本バスが出ているようです。

    奥多摩駅時刻表
    http://transfer.navitime.biz/bus-navi/pc/diagram/BusDiagram?orvCode=00042103&course=0000431622&stopNo=1

    深山橋→奥多摩駅行きの時刻表
    http://transfer.navitime.biz/bus-navi/pc/diagram/BusDiagram?orvCode=00042635&course=0000430401&stopNo=19&orvName=%E6%B7%B1%E5%B1%B1%E6%A9%8B&poleId=

    [adsense2]

    gnuplotで複数のグラフを載せる

    gnuplotで複数の図を載せたい時はmultiplotを使います。

    うまくmultiplotを使いこなすポイントは、
    ・1つ1つの図の上下左右の絶対位置を指定する
    ・eps画像のサイズを決定する
    ・トライ&エラー
    です。

    multiplotとは


    multiplotとは、その名の通り複数の図を同時にgnuplot上で表示させることです。
    これを使うと、図同士の比較が出来たり、insetを入れることが出来るようになります。

    さて、gnuplotには標準で横2行×縦3列など決まったレイアウトのmultiplotが出来る

    set multiplot layout 2,3

    というコマンドが存在しますが、ここではlayoutは使いません。
    なぜなら、グラフの細かい調整が出来ないからです。例えば、2つの図でx軸を共有させたい場合がありますがこれはlayoutを使うと出来ません。なので、これに頼らない方法を紹介します。

    2枚の図を同時に表示させたいとします。
    この時、2枚の図の位置を、

    set lmargin screen 0.3
    set rmargin screen 0.9
    set tmargin screen 0.9
    set bmargin screen 0.7

    のように指定します。lmarginなどは↓の図位置の長さを指定しています。

    座標は絶対位置で、左下を座標(x,y)=(0,0)にとり、右上を(x,y)=(1,1)として考えます。

    座標(1,1)は出力形式で設定したサイズを表しています。
    例えば、サイズを横3インチ、縦5インチに設定した場合、座標(0.5,0.5)は横1.5インチ、縦2.5インチの座標を表しています。

    これは重要なことです。
    今、完成した画像を完全な正方形のグラフにしたいとします。
    この時、座標を縦横0.5のサイズを持つようにとったとしても、出力形式のサイズが正方形でない限り完成した図が正方形になることはないことを意味しています。

    x軸を共有したい場合


    x軸を共有したい場合、
    1枚目の画像(青線)のbmargin

    2枚目の画像(緑線)のtmargin
    を一致させ、lmarginとrmarginを一致させると良いでしょう。
    この場合↓の図のように考えます。

    実例がこちら。

    コードの中身はこんな感じ。

    清書

    上の図を少し綺麗にしてみました。
    書式やticsは引き継がれるので、各々のplotの前にできる限り記述をしたほうが良いでしょう。

    縦軸と横軸を共通に


    縦軸と横軸を共通にしたい場合はこんな感じにとれば良いです。

    実例

    コードの中身はこんな感じ。

    insetを入れる


    注意する点は、2番目のグラフが1番目のグラフの上に来る、ということです。

    また、insetは背景を白くするために白色のオブジェクト

    set object 1 rect behind from screen 0.3,0.2 to screen 0.6,0.5 fc rgb "#ffffff" fillstyle solid 1.0

    を入れています。デフォルトでは透過してしまうためです。

    Note


    アイキャッチのフォントは “Commune-Round”を用いています。 http://www.gebsite.org/

    時間依存しないシュレーディンガー方程式と変分原理 2/2 (計算例)

    計算例


    具体的に適当なポテンシャルの形を考えて解いてみましょう。

    プログラムは
    時間依存しないシュレーディンガー方程式と変分原理 1/2
    にあります。

    おさらいですが、間接法による変分原理は、

    • 固有値の上限を与える(変分原理によるエネルギー固有値は必ず厳密なエネルギー固有値よりも大きくなる)
    • 基底関数の数を増やすほど精度は上がる(完全系の場合)

    ということを想定しています。
    そして、時間依存しないシュレーディンガー方程式と変分原理 1/2 (計算手法の説明)
    では、これから束縛状態のみを考えるので、sin関数系の場合の変分原理について計算を行っていきました。
    上に想定した変分原理の想定は、

    正しい境界条件の下で誤差なく行列要素が求められ、誤差なく対角化が行われた

    場合にのみ成り立ちます。sin関数系の場合の境界条件は固定端条件、つまり区間[a,b]で
    \(
    \psi(x=a)=\psi(x=b)=0
    \)

    ということです。

    ここでは、解析的な解が存在する

    1. 井戸型ポテンシャル
    2. 三角量子井戸
    3. 調和ポテンシャル
    4. F.モースによるポテンシャル[3]
    5. \(1/(\cosh^2)\)型ポテンシャル[3]
    6. クーロンポテンシャル(動径方向, \(l=0\))

    について比較していきます。

    シュレーディンガー方程式は全て原子単位系(\(m=1, \hbar=1\))で考え、
    \(
    \displaystyle \left[-\frac{1}{2}\frac{d^2}{dx^2}+V(x)\right]\psi(x)=E\psi(x)
    \)

    の形を考えます。

    無限に深い井戸型ポテンシャル


    ポテンシャル

    \(
    V(x)=\left\{
    \begin{eqnarray}
    0 \hspace{2em}&(& 0\lt x \lt L,)\\
    \infty \hspace{2em}&(& x\le 0 \ or\ L\le x)
    \end{eqnarray}
    \right.
    \)

    ※井戸の区間が\([a,b]\)であっても変数変換\(y=x-a,\;\;L=b-a\)によって上記ポテンシャルの形に変換されます。

    固有値

    \(
    \displaystyle E_n=\frac{(n+1)^2\pi^2}{2 L^2},\;\;(n=0,1,2,\cdots)
    \)

    固有関数

    \(
    \psi_n(x)=\left\{
    \begin{eqnarray}
    \sqrt{\frac{2}{L}}\sin\left(\frac{(n+1)\pi}{L}(x+\frac{L}{2})\right) &(& 0\lt x \lt L,)\\
    0 \hspace{6em}&(& x\le 0 \ or\ L\le x)
    \end{eqnarray}
    \right.
    \)

    解法

    区間\(0\lt x \lt L,\)ではシュレーディンガー方程式の\(V(x)=0\)の解、sin,cosの形をしてなければなりません。
    また、\(\psi(x=0)=0,\;\psi(x=L)=0\)では境界条件より、波動関数の値はゼロです。
    よって、解はsin,cosの形で、そのゼロ点がちょうど\(x=0,x=L\)にくるような関数となります。

    数値計算解と解析解との比較

    数値計算の設定:
    Gauss-Lobatto求積法の次数(Ngl):12
    計算区間(a,b):[0,\(\pi\)]
    基底関数の数(N):200

    エネルギー固有値

    量子数\(n\) 数値計算解 解析解
    0 0.5000000000000000 0.5000000000000000
    1 2.0000000000000000 2.0000000000000000
    2 4.5000000000000000 4.5000000000000000
    3 8.0000000000000000 8.0000000000000000
    4 12.5000000000000000 12.5000000000000000
    10 60.500000000000000 60.500000000000000
    20 220.50000000000000 220.50000000000000
    30 480.50000000000000 480.50000000000000
    40 840.50000000000000 840.50000000000000
    50 1300.5000000000000 1300.5000000000000
    考察

    行列は元々対角です。なので、対角化する前から対角行列です。
    誤差は入りようがありません。

    三角量子井戸


    ポテンシャル

    \(
    V(x)=\left\{
    \begin{eqnarray}
    \infty \hspace{2em}&(& x\lt 0)\\
    \alpha x \hspace{2em}&(& 0 \lt x)
    \end{eqnarray}
    \right.
    \)

    固有値

    \(
    \displaystyle E_n=-\left(\frac{\alpha^2}{2}\right)^{1/3}a_n
    \)

    ここで、\(a_n\)はAiry関数[4]のゼロ点です。

    固有関数

    \(
    \displaystyle \psi_n(x)=C\cdot \text{Ai}\left(\left(\frac{2}{\alpha^2}\right)^{1/3}(\alpha x-E_n)\right)
    \)

    ※積分区間がエアリー関数のゼロ点から無限までであり、これは解析的に実行できません。なので規格化定数をあらわに書くことはできません。

    解法

    区間\(0\lt x \lt \infty,\)ではシュレーディンガー方程式の\(V(x)=\alpha x\)の解、Airy関数の形をしてなければなりません。
    また、\(\psi(x=0)=0, \psi(x\to \infty)=0\)の境界条件を満たします。
    よって、解はAiry関数の形で、\(x\)が漸近で減衰していく方の解(\(Ai(x),Bi(x)\)のAiの方)で、そのゼロ点がちょうど\(x=0\)にくるような関数となります。

    数値計算解と解析解との比較

    数値計算の設定:
    Gauss-Lobatto求積法の次数(Ngl):12
    計算区間(a,b):[0,60]
    基底関数の数(N):200
    \(\alpha\):1

    エネルギー固有値

    量子数\(n\) 数値計算解 解析解
    0 1.8557572021449626 1.8557570814892386
    1 3.2446077578572123 3.2446076240031596
    2 4.3816713853293896 4.3816712392861303
    3 5.3866139387958034 5.3866137807905003
    4 6.3052631766282223 6.3052630065857747
    10 10.8669422991860358 10.8669420487522821
    20 16.8461591354108187 16.8461586901918032
    30 21.8969186983512394 21.8969179157570224
    40 26.4182318860569758 26.4182304793452509
    50 30.5803380635310234 30.5803354172938597

    考察

    上記計算では基底状態から励起状態までほとんど精度が変わっていません。
    また、変分原理が想定したとおり、全ての数値計算解は、厳密な解よりも高い結果を与えています。
    厳密な解よりも高い結果を与えていることから、
    行列要素は高精度で計算されているが、基底関数が足らない、もしくは計算区間が足らない
    事が考えられます。

    精度がなぜ良くないのかを考えましょう。
    \(x=0\)の境界条件は\(\sin\)関数で良く表現されます。が、\(x\to\infty\)側は指数関数で減少していきます。
    (一次の)指数関数で減衰していくことを\(\sin\)関数系ではうまく表現できないのではないか、と思います。
    実際、Airy関数の指数関数での減衰は漸近で
    \(
    \displaystyle \frac{e^{-\frac{2}{3}x^{3/2}}}{x^{1/4}}
    \)

    と表されます。
    この後、調和ポテンシャルとクーロンポテンシャルの場合も考えますが、
    調和ポテンシャル(漸近で\(\exp(-x^2)\)、基底状態の精度14,15桁)

    三角量子井戸(漸近でおおよそ\(\exp(-x^{2/3})\)、基底状態の精度7,8桁)

    クーロンポテンシャル(漸近で\(\exp(-x)\)、基底状態の精度2,3桁)
    の順に精度が悪くなっていきます。
    指数関数的な減衰が早い≒無限に深い量子井戸
    を意味するはずなので、恐らくこうなのではと思います。

    調和ポテンシャル



    \(
    \displaystyle V(x)=\frac{1}{2}x^2
    \)

    固有値

    \(
    \displaystyle E_n=n+\frac{1}{2},\;\;(n=0,1,2,\cdots)
    \)

    固有関数

    \(
    \displaystyle \psi_n(x)=\frac{\pi^{-1/4}}{\sqrt{2^n n!}}e^{-\frac{x^2}{2}} H_n\left(x\right)
    \)
    ここで\(H_n(x)\)はエルミート多項式を表します。

    解法

    1次元調和振動子の直接解法

    数値計算解と解析解との比較

    数値計算の設定:
    Gauss-Lobatto求積法の次数(Ngl):12
    計算区間(a,b):[-30,30]
    基底関数の数(N):200

    量子数\(n\) 数値計算解 解析解
    0 0.5000000000000038 0.5
    1 1.5000000000000340 1.5
    2 2.4999999999998268 2.5
    3 3.4999999999996776 3.5
    4 4.4999999999999165
    10 10.4999999999999680 10.5
    20 20.4999999999997691 20.5
    30 30.5000000000065015 30.5
    40 40.5000064794500432 40.5
    50 50.5426649449273313 50.5
    考察

    変分原理の典型的な傾向を見せています。というのは高い励起状態になればなるほど精度が悪くなっているためです。
    高励起状態になるにつれて精度が悪くなっていくのは基底関数が足らない為でしょう。計算区間に関してはポテンシャルは境界で高いまま(\(V(a)=V(b)=450\))であり、求められたエネルギー固有値の値\(E_{50}\approx 50\)と比べても十分大きいです。なので、計算区間は足りています。

    また、変分原理の固有値の上限を与えるに関しては必ずしも満たしているわけでは無いことに気が付きます。これは行列要素を求める際の誤差や丸め誤差に起因するものであると考えられます。なので、原理が破られているのではなく、数値計算上の問題に起因しています。\(n=30,40,50\)では厳密解よりも大きな値を与えています。これは、数値計算上の誤差よりも変分原理の原理的な値の方が大きくなっているためです。

    F.モースによるポテンシャル[3]



    \(
    \displaystyle V(x)=A\left(e^{-2\alpha x}-2e^{-\alpha x}\right)
    \)

    固有値

    \(
    \displaystyle E_n=-A\left[1-\frac{\alpha}{\sqrt{2A}}\left(n+\frac{1}{2}\right)\right]^2
    \)

    ここで、\(n\)は正の整数で、ゼロから始まり、
    \(
    \displaystyle\frac{\sqrt{2A}}{\alpha}\gt n+\frac{1}{2}
    \)

    を満足する最大値\(n_{\text{max}}\)まで。

    固有関数

    \(
    \begin{align}
    \psi(x)&=e^{-\xi/2} \xi^s w(\xi) \\
    & w(\xi)=F(-n,2s+1,\xi) \\
    & \xi=\frac{2\sqrt{2A}}{\alpha}e^{-\alpha x} \\
    & s=\frac{\sqrt{-2E}}{\alpha}
    \end{align}
    \)
    ここで\(F(a,b,x)\)は合流型超幾何関数です。

    この問題では離散スペクトルは有限個だけ存在します。もしも
    \(
    \displaystyle\frac{\sqrt{2A}}{\alpha}\gt n+\frac{1}{2}
    \)

    であれば、離散スペクトルは一般に存在しません。

    解法

    [3]を参照してください

    数値計算解と解析解との比較

    数値計算の設定:
    Gauss-Lobatto求積法の次数(NGL):12
    計算区間(a,b):[-3,80]
    基底関数の数(N):200
    \(A\):5
    \(\alpha\):1

    エネルギー固有値

    量子数\(n\) 数値計算解 解析解
    0 3.5437173567132851 -3.5438611699158100
    1 1.3814252908344455 -1.3815835097474309
    2 0.2185797147047042 -0.2193058495790518
    3 -0.0049226123802256
    4 0.0081675032299395
    10 0.0527783252864115
    20 0.2666761210195411
    30 0.6404251854103465
    40 1.1703593933291645
    50 1.8543552927405405
    考察

    厳密解は3つしか存在しません。この3つの状態に対しては数値計算解の方が厳密解よりも大きくなり、想定通りです。
    しかし精度があまり良くありません。これはポテンシャルが\(V(x\to\infty)=0\)であり、波動関数が速やかにゼロに向かわないためだろうと考えられます。
    また、基底状態でもあまり良い結果が得られていません。上記ポテンシャルの閉じ込めが強くなく、多くの基底関数が必要となり、数値計算で用いた200個では十分ではないのでしょう。

    4つ目の解に注目しましょう。厳密解は存在しないのに数値計算ではあたかも解が存在するように見えます(\(E\le 0\))。また、変分原理は上限を与えるため、4つ目の解が存在すると考えてしまうかもしれません。しかし、これは違います。明らかにするために4つ目の解の波動関数の形(青色の線)を拡大してみますと、

    となり、物理的に意味を成していないことが分かります。なぜなら、波動関数は\(x\to\infty\)に向かうにつれて徐々に小さくなっていかなければなりません。もしもこれが正しければ、\(x=80\)で節を持っている解ということになり、これは束縛状態の解としては適しません。

    エネルギー固有値だけを考えては求められないものだったということですね。

    さらに、束縛状態以上ではすべて連続状態です。それにもかかわらず\(E\gt 0\)でも離散的に固有値が得られているのは基底関数に固定端の境界条件を課しているためです。これらに物理的な意味は無いので評価する際には気を付けましょう。

    \(1/(\cosh^2)\)型ポテンシャル[3]



    \(
    \displaystyle V(x)=-\frac{V_0}{\cosh^2 \alpha x}
    \)

    固有値

    \(
    \displaystyle E_n=-\frac{\alpha^2}{8}\left[-(1+2n)+\sqrt{1+\frac{8V_0}{\alpha^2}}\right]^2
    \)

    で、\(n\)は
    \(
    \displaystyle n\lt s = \frac{1}{2}\left(-1+\sqrt{1+\frac{8V_0}{\alpha^2}}\right)
    \)

    から有限個の準位が決まります。

    固有関数

    \(
    \begin{align}
    \psi(x)&=(1-\xi^2)^{\xi/2}F\left[\varepsilon-s, \varepsilon+s+1, \varepsilon+1, \frac{1-\xi}{2}\right]\\
    & \varepsilon=\frac{\sqrt{-2E}}{\alpha}\\
    & \xi=\tanh \alpha x
    \end{align}
    \)

    ここでの\(F(a,b,c,x)\)は超幾何関数です。

    解法

    [3]を参照してください

    数値計算解と解析解との比較

    数値計算の設定:
    Gauss-Lobatto求積法の次数(NGL):12
    計算区間(a,b):[-30,30]
    基底関数の数(N):200

    エネルギー固有値

    量子数\(n\) 数値計算解 解析解
    0 3.8286053565505553 -3.885009803959261
    1 1.9750293441823026 -1.9750294118777854
    2 0.6459145040771800 -0.7050490197963089
    3 0.0750649726143545 -0.0750686277148326
    4 0.0076704714372625
    10 0.1139873400292487
    20 0.4849841979196881
    30 1.1689850012563472
    40 2.1388129318397651
    50 3.3888397726738235
    考察

    エネルギー固有値の上限を確かに与えています。そのほかはおおよそF.モースによるポテンシャルと同じような結果を与えています。

    精度に関して、エネルギー固有値の精度は\(n=0,2\)の時、1~2桁程度の精度ですが、\(n=1,3\)の時、は6~7桁一致と著しく精度が上がっています。計算区間を変えたりしたのですが、この傾向は変わりません。
    なぜなのか…詳しくは分かりません。偶関数、奇関数の問題だと思います。すなわち、奇関数の場合はなにか\(x\gt 0\)の領域に誤差があっても同じ量の誤差で\(x\lt 0\)で打ち消し合ってくれるのですが、偶関数の場合は打ち消し合いが起きないのではないか、ということです。
    ただ、これが行列要素の精度からくるものなのかは詳しく見ていないので分かりません…

    クーロンポテンシャル(動径方向, \(l=0\))


    ポテンシャル

    \(
    \displaystyle V(x)=-\frac{1}{x}
    \)

    ※ここでは、一階微分の存在しない形にした時のシュレーディンガー方程式を考えています。

    固有値

    \(
    \displaystyle E_n=-\frac{1}{2n^2},\;\;(n=1,2,\cdots,)
    \)

    です。

    固有関数

    \(
    \begin{align}
    \psi(x)=C \cdot e^{-x/n} x^l L_{n-1}^{(1)}(x)
    \end{align}
    \)

    ここで,\(C\)は規格化定数, \(L_n^k(x)\)はラゲール倍多項式[5]で
    \(
    \begin{align}
    L_0^k(x)&=1 \\
    L_1^k(x)&=-x+k+1 \\
    L_2^k(x)&=\frac{1}{2}[x^2-2(k+2)x+(k+1)(k+2)] \\
    L_3^k(x)&=\frac{1}{6}[-x^3+3(k+3)x^2-3(k+2)(k+3)x+(k+1)(k+2)(k+3)]
    \end{align}
    \)
    です。もちろん規格化定数をあらわに決めることが出来ますが、通常、この問題は3次元のシュレーディンガー方程式を解いた時の動径方向として出てくるので、その時の規格化は
    \(
    \displaystyle \int_0^\infty x^2 \psi(x)^2 dx =1
    \)

    で規格化されます。しかし、本稿の規格化は\(\displaystyle \int_0^\infty \psi(x)^2 dx =1\)
    で規格化しているので、エネルギー固有値のみの比較を行います。

    解法

    \(x=0, x\to infty\)の漸近形を考えて、本当の解を
    (\(x=0\)の漸近形)×(\(x=\infty\)の漸近形)×(未知関数)
    と仮定します。これをシュレーディンガー方程式に代入すると未知関数がラゲール陪多項式だと分かります。

    数値計算解と解析解との比較

    数値計算の設定:
    Gauss-Lobatto求積法の次数(NGL):12
    計算区間(a,b):[0,80]
    基底関数の数(N):200

    エネルギー固有値

    量子数\(n\) 数値計算解 解析解
    1 0.4970775696080274 -0.5000000000000000
    2 -0.1246297940063756 -0.1250000000000000
    3 0.0554455545682885 -0.0555555555555556
    4 0.0312035408553899 -0.0312500000000000
    5 0.0199704293764349 -0.0200000000000000
    6 0.0134298208377274 -0.0138888888888889
    7 0.0068151982214300 -0.0102040816326531
    8 0.0018616612074302 -0.0078125000000000
    10 0.0251247065596211 -0.0050000000000000
    20 0.2439421094228725 -0.0012500000000000
    考察

    クーロンポテンシャルの場合、\(x=\infty\)では波動関数は指数関数で減衰していきます。
    このため、減衰がゆっくりになってしまい、sin関数でうまく表現できないために精度が落ちているのだと推測できます。
    また、計算区間を十分に大きく取ると励起状態の表現はうまくいきますが、反対に基底状態の表現ができなくなります。なぜなら、多くの区間で波動関数はゼロですが、\(x=0\)の近傍だけに大きなピークを持つため、sin関数ではうまく表現できません。その兆候は上の数値計算でも見えてます。基底状態は2桁程度ですが、量子数の増加と共に1桁くらい精度が上がっています。
    クーロンの場合、ラゲール関数を基底関数としてとる方が良いでしょう。

    参考文献


    [1]P. J. Davis, P. Rabinowitz著, 森正武訳, 「計算機による数値積分法」, Gauss-Lobatto求積法 p.88
    [2]P. J. Davis, P. Rabinowitz著, 森正武訳, 「計算機による数値積分法」, ゼロ点に挟まれる区間の積分 p.131
    [3]ランダウ=リフシッツ,「量子力学1」第3刷, p81-84
    [4]Abramowitz and Stegun, HANDBOOK OF MATHEMATICAL FUNCTIONS, p.446,478 http://people.math.sfu.ca/~cbm/aands/page_446.htm

    Airy関数のゼロ点は
    エアリー関数 Ai, Bi(ゼロ点)-Keisan
    より22桁の精度で求めたものを用いています。
    ちなみにそれらの値(Airy関数のゼロ点)は、

    0 -2.338107410459767038489
    1 -4.087949444130970616637
    2 -5.52055982809555105913
    3 -6.78670809007175899878
    4 -7.944133587120853123138

    10 -13.6914890352107179283
    20 -21.2248299436420969552
    30 -27.58838780988244481195
    40 -33.28488468190140187962
    50 -38.52880830509424882263

    です。ゼロ点を0,1,2,…と、今回の計算の都合上0からインデックスを付けています。
    もしかすると最後の1~2桁はあってないかもしれませんが、本稿では16桁まであっていればいいので、問題ありません。

    [5]
    Associated Laguerre Polynomial -wolfram mathworld式(22)-(25)