[ 前へ | 目次 | 次へ ]
Now Loading...
ダウンロード
PC (※スマートフォンでは動きません) でダウンロードし、ZIPファイルを右クリックメニューから展開して、できたフォルダ内の「 VCSSL.bat(バッチファイル) 」または「 VCSSL.jar 」をダブルクリックなどで実行すると、プログラムが起動します。
» 詳しい使用方法や、エラーで展開できない際の対応方法などはこちら

ローレンツアトラクタ(GUI版)

ローレンツ方程式を4次精度ルンゲ=クッタ(RK4)法で数値的に解き、その解曲線を描くVCSSLプログラムです。描かれる解曲線は、 「 ローレンツアトラクタ 」として非常に有名です。

なお、このプログラムでは、GUIの設定パネルでパラメータを変更でき、操作に応じてリアルタイムで再計算してグラフに描画するような仕組みになっています。 それに対して、計算結果をファイルに出力して、それをグラフでプロットする、より単純なバージョンも下記にて公開しています。コード内容はそちらのほうが単純で、C言語への書き換えなども容易です。

上のファイル出力版では、計算結果を一旦ファイルに書き出すため、VCSSL付属のグラフ機能だけではなく、一般のグラフソフトで解析する事もできます。

対して今回のGUI版では、リアルタイム計算を行うのでファイルは出力しませんが、GUI設定パネルのスライダーでパラメータを操作でき、それに応じて結果のグラフも自動的に再描画されるため、手軽に楽しむ事ができます。

使用方法

ダウンロードと展開方法

まず、PC(スマホは未対応)で上の画面の「 ダウンロードして実行 」ボタンを押してください。 するとZIP形式で圧縮されたファイルがダウンロードされるので、そのZIPファイルを右クリックして「すべて展開」や「ここに展開」などで展開してください。 展開が成功すると、ZIPファイルと同じ名前のフォルダができ、その中にZIPファイルの中身が入っています。

» 展開がエラーで止まってしまう場合は…

なお、Linux® 等をご使用で、右クリックメニューから展開するとファイル名が文字化けしてしまう場合は、 コマンドライン端末でZIPファイルのある場所まで cd した上で「 unzip -O cp932 ZIPファイル名 」で展開してみてください。

起動方法

Microsoft® Windows® をご使用の場合

上記の通りにZIPファイルを展開したフォルダ内にある、 「 VCSSL.bat(種類はバッチファイル) 」をダブルクリック実行してください。 もしプログラムの内容を書き変えながら使いたい場合は、代わりに「 VCSSL_Editor.bat 」を実行してください。

実行すると、最初にメモリー使用量や、(必要な場合のみ)Java®実行環境を自動で入手するか 等を尋ねられるので、適時答えると、プログラムが起動します。2回目以降はすぐに起動します。

※ ここで入手したJava®実行環境は、ZIPファイルを展開した中の「 jre 」フォルダ内にダウンロードされ、このプログラムの実行のみに使用されます。PC全体に影響する形でインストールされる事はありません。

Linux® 等やその他のOSをご使用の場合

ZIPファイルを展開したフォルダ内へコマンドライン端末で cd して、以下の通り入力して実行してください:

java -jar VCSSL.jar
(プログラムの内容を書き変えながら使いたい場合は、代わりに VCSSL_Editor.jar を実行)

» javaコマンドが使用できない等のエラーが表示される場合は…

操作方法

プログラムを実行すると、3Dグラフのウィンドウと、スライダーを備えたウィンドウが表示されます。 3Dグラフのウィンドウには、ローレンツ方程式の積分解曲線( ローレンツアトラクタ )が描画されます。 スライダーを備えたウィンドウでは、ローレンツ方程式のパラメータ値を調整できます。スライダーを操作すると、パラメータ値が変化し、それに応じて3Dグラフがリアルタイムで再描画されます。

アニメーション描画

「ANIMATION」ボタンをクリックすると、ローレンツアトラクタを始点から徐々に描いていくアニメーションを見る事ができます。

終了方法

終了の際は、スライダーを備えたウィンドウの右端にある、「 END 」ボタンを押してください。

題材解説

ローレンツ方程式とローレンツアトラクタ、初期値鋭敏性

ローレンツ方程式は、以下の形で表される、1階の常微分方程式です。

\[ \frac{dx}{dt} = -sx + sy \] \[ \frac{dy}{dt} = -xz + ry - y \] \[ \frac{dz}{dt} = xy - bz \]

この方程式は、極めてシンプルかつ決定論的な方程式であるにもかかわらず、それが描く曲線が、 かなりランダム的な振る舞いを帯びる事が特徴です。

アニメーション描画で見てみるとよくわかりますが、始点から伸びていった起動は、 右へ左へと何度もロールを描きながら、蝶の羽のような特徴的な曲線 ― ローレンツアトラクタ ― を描いていきます。

そして、この奇妙なロールのパターン ― 右、左、右、右、左、右、…というような不規則的なパターン ― は、ちょうど天気予報のように、未来の予測が極めて困難な、ランダム的なものとなります。

例えば、今の瞬間から、次に右へロールするか、左へロールするかは、比較的簡単に予測できます。 しかし数回後にどちらへロールするかは、それなりに高精度に計算しないと、予測がはずれてしまいます。 さらに数十回後を予測しようとすると、一気に必要な精度のハードルが高くなります。 つまり、より遠い未来を予測しようとするほど、飛躍的に高い計算精度が必要となるのです。

この性質の発見により、今日「カオス」と呼ばれている、非常に有名な物理学の分野が開拓されました。 この性質は、現在のカオスの分野では「初期値鋭敏性 」と呼ばれており、 カオスモデルの持つ重要な性質の一つに位置づけられています。

天気予報の難しさ

気象学者であったエドワード・ローレンツ氏は、流体のシミュレーションモデルとしてこの方程式を使用し、 そしてこのような極めて単純な数理モデルでも、現実的には予測不能な振る舞いが生じるという事を見出しました。

この事は今日、いわゆる 「 バタフライ効果 ( 地球の裏側で蝶が羽ばたいただけで、未来の気象が全く変わってしまうという例え話 ) 」 などとして、一般にもよく知られています。

この事から、天気予報の難しさを説明する際に、 今日でも頻繁にローレンツアトラクタが例に挙げられます。 数あるカオスモデルの中でも、恐らく最も有名なものの一つでしょう。

コード解説

プログラム内容

はじめに、少し長いですが、プログラム全体を掲載します。以下の通りです。

処理フロー

このプログラムでは、スライダーでパラメータ値が変更されるたびに再度処理を行う必要があるため、メインループ型の処理フローを用いています。

メインループとは、プログラム開始時から終了時まで繰り返し続けるループの事で、イベント処理のために広く一般的に使用されています。 なお、メインループは、イベントループや基本ループなど、用途や分野によって別の名称で呼ばれる事もあります。

メインループ内で毎回、再計算が必要かどうかを確認し、必要なら再計算と再描画を行っています。


void main( string args[] ){

  // 初期化など

  // メインループ、プログラム終了まで繰り返し
  while( MAIN_ROOP ){

    // 再計算が必要かどうかを判定
    if( PLOT_REQUEST ){

      //---------------
      //ここで計算
      //---------------

      PLOT_REQUEST = false;

    }else{

      sleep( 100 );

    }

  }

  exit();

}

上のPLOT_REQUESTはbool型変数で、再計算が必要な場合にtrueになっています。この変数はスライダーのイベントハンドラでtrueにし、メインループで再計算が完了したらfalseにします。

微分方程式を数値的に解く

このVCSSLプログラムでは、ローレンツ方程式を4次収束ルンゲ=クッタ(RK4)法で数値的に解いています。RK4法は、この種の解法の方法の中でも高精度な部類に属します。 RK4法の計算を行っているのは、プログラム中の以下の部分です。


x = 0.1;
y = 0.1;
z = 0.1;

for( int i=0; i<N; i++ ){

  // Integration ( RK4 )

  k1_x = f_x( x, y, z );
  k1_y = f_y( x, y, z );
  k1_z = f_z( x, y, z );

  k2_x = f_x( x+k1_x*DT*0.5, y+k1_y*DT*0.5, z+k1_z*DT*0.5 );
  k2_y = f_y( x+k1_x*DT*0.5, y+k1_y*DT*0.5, z+k1_z*DT*0.5 );
  k2_z = f_z( x+k1_x*DT*0.5, y+k1_y*DT*0.5, z+k1_z*DT*0.5 );

  k3_x = f_x( x+k2_x*DT*0.5, y+k2_y*DT*0.5, z+k2_z*DT*0.5 );
  k3_y = f_y( x+k2_x*DT*0.5, y+k2_y*DT*0.5, z+k2_z*DT*0.5 );
  k3_z = f_z( x+k2_x*DT*0.5, y+k2_y*DT*0.5, z+k2_z*DT*0.5 );

  k4_x = f_x( x+k3_x*DT, y+k3_y*DT, z+k3_z*DT );
  k4_y = f_y( x+k3_x*DT, y+k3_y*DT, z+k3_z*DT );
  k4_z = f_z( x+k3_x*DT, y+k3_y*DT, z+k3_z*DT );

  x += ( k1_x + 2.0*k2_x + 2.0*k3_x + k4_x )*DT/6.0;
  y += ( k1_y + 2.0*k2_y + 2.0*k3_y + k4_y )*DT/6.0;
  z += ( k1_z + 2.0*k2_z + 2.0*k3_z + k4_z )*DT/6.0;

  ORBIT_X[ i ] = x;
  ORBIT_Y[ i ] = y;
  ORBIT_Z[ i ] = z;

}

配列ORBIT_X、 ORBIT_Y、 ORBUT_Z は、軌道のX、Y、Z座標を格納する配列です。forの1ループごとに、軌道座標の新たな1点をRK4法で計算し、それを配列に格納しています。

この部分はローレンツ方程式に限らず、一般的な3次元の1階常微分方程式をRK4法て数値積分する場合に使用できます。

使用されている関数f_x、f_y、f_zは、X、Y、Z値を引数にして、その点における微分係数dx/dt、dy/dt、dz/dtを返します。

ここではローレンツ方程式を積分しているので、以下のように定義しています。


// dx / dt
macro f_x( float X, float Y, float Z ){
  return -PARAM_S*X + PARAM_S*Y;
}

// dy / dt
macro f_y( float X, float Y, float Z ){
  return -X*Z + PARAM_R*X - Y;
}

// dz / dt
macro f_z( float X, float Y, float Z ){
  return X*Y - PARAM_B*Z;
}


 この関数は非常に処理内容が少ないので、コール時のオーバーヘッドを回避するため、マクロ関数として定義しています。

グラフ描画


 全ての座標点の計算が終了し、軌道の全座標が求まった後は、それを格納する配列ORBIT_X、 ORBIT_Y、 ORBUT_Zを3Dグラフソフトに転送し、描画を行っています。


// 座標値配列を3Dグラフソフトに転送し、再描画
setGraph3DData( graph, ORBIT_X, ORBIT_Y, ORBIT_Z );

なお、3Dグラフはこのように描画命令を送る前に、プログラム先頭であらかじめ生成処理とオプション設定を行っています。


// 3Dグラフソフトを生成
int graph = new Graph3D( 0, 0, 600, 500, "Graph Window" );

// 線描画オプションをONに設定
setGraph3DOption( graph, "WITH_LINES", true );


スライダーなどのGUI設計


 以下の関数 createSettingWindow では、スライダーなどのGUIを生成し、ウィンドウ上に配置しています。この関数はプログラム開始後の初期化部分でコールしています。


int WINDOW;
int PARAM_S_SLIDER, PARAM_B_SLIDER, PARAM_R_SLIDER;
int PARAM_S_LABEL, PARAM_B_LABEL, PARAM_R_LABEL;
int END_BUTTON;

void createSettingWindow(){

  WINDOW = newWindow( 0, 500, 600, 200, "Setting Window" );

  int explainLabel1 = newTextLabel( 10, 10, 400, 15, "dx / dt = - S * x + S * y" );
  mountComponent( explainLabel1, WINDOW );
  int explainLabel2 = newTextLabel( 10, 25, 400, 15, "dy / dt = - x * z + R * x - y" );
  mountComponent( explainLabel2, WINDOW );
  int explainLabel3 = newTextLabel( 10, 40, 400, 15, "dz / dt = x * y - B * z" );
  mountComponent( explainLabel3, WINDOW );

  PARAM_S_LABEL = newTextLabel( 10, 60, 400, 15, "S = "+PARAM_S );
  mountComponent( PARAM_S_LABEL, WINDOW );
  PARAM_S_SLIDER = newHorizontalSlider( 10, 75, 400, 15, PARAM_S/50.0 );
  mountComponent( PARAM_S_SLIDER, WINDOW );

  PARAM_B_LABEL = newTextLabel( 10, 90, 400, 15, "B = "+PARAM_B );
  mountComponent( PARAM_B_LABEL, WINDOW );
  PARAM_B_SLIDER = newHorizontalSlider( 10, 105, 400, 15, PARAM_B/50.0 );
  mountComponent( PARAM_B_SLIDER, WINDOW );

  PARAM_R_LABEL = newTextLabel( 10, 120, 400, 15, "R ="+PARAM_R );
  mountComponent( PARAM_R_LABEL, WINDOW );
  PARAM_R_SLIDER = newHorizontalSlider( 10, 135, 400, 15, PARAM_R/500.0 );
  mountComponent( PARAM_R_SLIDER, WINDOW );

  END_BUTTON = newButton( 420, 10, 150, 140, "END" );
  setComponentFontSize( END_BUTTON, 30 );
  mountComponent( END_BUTTON, WINDOW );

  paintComponent( WINDOW );

}

イベントハンドラ

スライダーが操作された際は、onSliderMoveイベントハンドラで受け取り、ローレンツ方程式のパラメータ値を再設定しています。そしてPLOT_REQUESTをtrueにし、メインループで再計算と再描画が行われるようにしています。


void onSliderMove( int id, float value ){

  if( id==PARAM_S_SLIDER ){

    PARAM_S = value * 50.0;
    setComponentText( PARAM_S_LABEL, "S = "+PARAM_S );
    paintComponent( PARAM_S_LABEL );

  }else if( id==PARAM_B_SLIDER ){

    PARAM_B = value * 50.0;
    setComponentText( PARAM_B_LABEL, "B = "+PARAM_B );
    paintComponent( PARAM_B_LABEL );

  }else if( id==PARAM_R_SLIDER ){

    PARAM_R = getComponentValue( PARAM_R_SLIDER ) * 500.0;
    setComponentText( PARAM_R_LABEL, "R = "+PARAM_R );
    paintComponent( PARAM_R_LABEL );

  }

  paintComponent( WINDOW );

  PLOT_REQUEST = true;

}

また、ENDボタンがクリックされたり、ウィンドウが閉じられた際には、それぞれのイベントハンドラでMAIN_ROOPをfalseにし、メインループを脱出させる事で、プログラムが終了するようにしています。


void onButtonClick( int ID ){

  MAIN_ROOP = false;

}

void onWindowClose( int ID ){

  MAIN_ROOP = false;

}

このようにする事で、全ての処理が終わったタイミングで exit 命令がコールされるため、プログラムの終了が必ず正常に行われます。

これに対し、イベントハンドラの中で直接 exit 命令をコールしてしまうと、メインループが処理中でも強制終了されてしまうため、終了時にエラーが出てしまう場合があります。

詳しいVCSSLのプログラミングガイド(無料)はこちらへ!

上記のコードはプログラミング言語VCSSLで記述されており、VCSSLのプログラミングガイドは下記で無料公開しています。 上記のコードを改造したい方や、新しいコードを書いてみたい方はぜひご活用ください!

スタートアップガイド( プログラミングがはじめての方向け )
プログラミングの入門書に相当する内容です。プログラミングが初めての方はこちらがおすすめです。
即席ガイド( C系言語ユーザー向け )
C言語や C++ などのC系の言語を扱われている方が、即席でVCSSLを扱うための簡易ガイドです。
文法ガイド
VCSSLの文法や基本的な機能を淡々とまとめた、リファレンスマニュアル的な位置づけのガイドです。
GUI開発ガイド
ボタンや入力項目などのGUI部品が並ぶ、画面を備えたVCSSLプログラムを開発するためのガイドです。
2DCG開発ガイド
画面上や画像ファイルなどに、2次元的な描画を行うVCSSLプログラムを開発するためのガイドです。
3DCG開発ガイド
画面上や画像ファイルなどに、3次元的な描画を行うVCSSLプログラムを開発するためのガイドです。
標準ライブラリ 仕様書
コード内で呼び出される関数は、大半が標準ライブラリのものです。その詳細仕様を掲載しています。

ライセンス

このVCSSLコード( 拡張子が「.vcssl」のファイル )は実質的な著作権フリー(パブリックドメイン) である CC0 の状態で公開しています。 そのままでのご利用はもちろん、言語の種類を問わず、改造や流用などもご自由に行ってください。

※ ただし、このVCSSLコードの配布フォルダ内には、ダウンロード後すぐに実行できるように、 VCSSLの実行環境も同梱されており、そのライセンス文書は「 License 」フォルダ内に同梱されています (要約すると、商用・非商用問わず自由に使用できますが、使用の結果に対して開発元は一切の責任を負いません、といった具合の内容です)。 配布フォルダ内の各構成物の一覧やライセンスについては「 ReadMe_使用方法_必ずお読みください.txt 」をご参照ください。

この記事中の商標などについて

  • OracleとJavaは、Oracle Corporation 及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
  • Windows は、米国 Microsoft Corporation の米国およびその他の国における登録商標です。この記事は独立著作物であり、Microsoft Corporation と関連のある、もしくはスポンサーを受けるものではありません。
  • Linux は、Linus Torvalds 氏の米国およびその他の国における商標または登録商標です。
  • その他、文中に使用されている商標は、その商標を保持する各社の各国における商標または登録商標です。


スポンサーリンク



[ 前へ | 目次 | 次へ ]
波の干渉(面上の円形波)のアニメーション表示

面上の円形波が干渉する様子を、パラメータを操作しながらアニメーションで見られるプログラムです。
円形波のアニメーション表示

振幅・波長・周期をスライダ―で操作しながら、円形波のグラフをアニメーションで見られるプログラムです。
波の干渉(線上の正弦波)のアニメーション表示

線上(1次元の)の正弦波が干渉する様子を、パラメータを操作しながらアニメーションで見られるプログラムです。
正弦波のアニメーション表示

振幅・波長・周期をスライダ―で操作しながら、正弦波のグラフをアニメーションで見られるプログラムです。
凹レンズを通過する波のシミュレーション

凹レンズ形状の高密度媒質を通過する、波のシミュレーションです。
凸レンズを通過する波のシミュレーション

凸レンズ形状の高密度媒質を通過する、波のシミュレーションです。
乱雑な密度分布における波のシミュレーション

密度分布が乱雑な媒質中における、波の伝播のシミュレーションです。
ローレンツアトラクタ(ファイル出力版)

4次精度ルンゲ=クッタ法により、ローレンツアトラクタを求めるプログラムです。
波の屈折のシミュレーション

密度の異なる領域を、波が屈折しながら通過するシミュレーションです。
力学アルゴリズムによる波のシミュレーション(面上の波)

媒質をバネと格子点で近似し、力学的なアルゴリズムで動かす事による、波のシミュレーションです。
手動で波を発生させるシミュレーション

スライダーをマウスで動かす事により、波を発生させるシミュレーションです。
力学アルゴリズムによる波のシミュレーション(線上の波)

媒質をバネと格子点で近似し、力学的なアルゴリズムで動かす事による、波のシミュレーションです。
二重振り子のシミュレーション

ラグランジュ方程式を用いた、二重振り子のシミュレーションです。
ローレンツアトラクタ(GUI版)

4次精度ルンゲ=クッタ法により、ローレンツアトラクタを求めるプログラムです。
スポンサーリンク

この階層の目次
[ 前へ | 目次 | 次へ ]
波の干渉(面上の円形波)のアニメーション表示

面上の円形波が干渉する様子を、パラメータを操作しながらアニメーションで見られるプログラムです。
円形波のアニメーション表示

振幅・波長・周期をスライダ―で操作しながら、円形波のグラフをアニメーションで見られるプログラムです。
波の干渉(線上の正弦波)のアニメーション表示

線上(1次元の)の正弦波が干渉する様子を、パラメータを操作しながらアニメーションで見られるプログラムです。
正弦波のアニメーション表示

振幅・波長・周期をスライダ―で操作しながら、正弦波のグラフをアニメーションで見られるプログラムです。
凹レンズを通過する波のシミュレーション

凹レンズ形状の高密度媒質を通過する、波のシミュレーションです。
凸レンズを通過する波のシミュレーション

凸レンズ形状の高密度媒質を通過する、波のシミュレーションです。
乱雑な密度分布における波のシミュレーション

密度分布が乱雑な媒質中における、波の伝播のシミュレーションです。
ローレンツアトラクタ(ファイル出力版)

4次精度ルンゲ=クッタ法により、ローレンツアトラクタを求めるプログラムです。
波の屈折のシミュレーション

密度の異なる領域を、波が屈折しながら通過するシミュレーションです。
力学アルゴリズムによる波のシミュレーション(面上の波)

媒質をバネと格子点で近似し、力学的なアルゴリズムで動かす事による、波のシミュレーションです。
手動で波を発生させるシミュレーション

スライダーをマウスで動かす事により、波を発生させるシミュレーションです。
力学アルゴリズムによる波のシミュレーション(線上の波)

媒質をバネと格子点で近似し、力学的なアルゴリズムで動かす事による、波のシミュレーションです。
二重振り子のシミュレーション

ラグランジュ方程式を用いた、二重振り子のシミュレーションです。
ローレンツアトラクタ(GUI版)

4次精度ルンゲ=クッタ法により、ローレンツアトラクタを求めるプログラムです。
お知らせ

各ソフトウェアの最新版を一括でリリース、OpenJDKのJava実行環境(JRE)に対応
2019年03月06日 - RINEARNでは3月6日に、主要なソフトウェアの最新版を一括でリリースしました。今回のアップデートには、以前お知らせした、OpenJDKで生成したJREへの対応が含まれています。その概要等をお知らせします。

次回のVCSSL 3.4.10において、関数1個の挙動に非互換な修正が適用されます
2019年02月12日 - VCSSLの次回の正式リリース版3.4.10において、これまでドキュメントと実際の挙動が異なっていた描画系の関数1個に、非互換な修正が適用されます。その詳細と、使用コードでの対応方法について解説します。

RINEARNのソフトウェア向けにOpenJDKで生成したJava実行環境(JRE)の提供を開始
2019年02月06日 - Javaのリリースモデル変更への対応として、OpenJDKのjlinkツールを用いて、RINEARNのソフトウェア実行用に生成したJava実行環境(JRE)の提供を開始しました。その詳細と、今後の方針について解説します。

新着
画像の矩形(四角形)領域を切り抜く簡易ツール(複数ファイル一括処理版)

フォルダ内にある全ての画像ファイルを開き、その中の矩形(四角形)領域を切り抜いて、別のフォルダに保存する簡易ツールです。
2019年03月15日
画像の矩形(四角形)領域を切り抜く簡易ツール

画像ファイルを開き、その中の矩形(四角形)領域を切り抜いて保存する簡易ツールです。
2019年03月14日
入力された数式を積分して値とグラフを表示するツール

画面上で数式を入力すると、それを数値的に積分し、値とグラフを表示してくれるGUIツールです。
2019年01月20日
z = f(x,y,t) の形の数式を3Dグラフとしてアニメーション描画するツール

入力欄に z = f(x,y,t) の形の数式を入力すると、それを3次元のグラフにアニメーション描画してくれる簡易ツールです。
2018年11月26日
y = f(x,t) の形の数式を2Dグラフとしてアニメーション描画するツール

入力欄に y = f(x,t) の形の数式を入力すると、それを2次元のグラフにアニメーション描画してくれる簡易ツールです。
2018年11月25日
開発元Twitterアカウント

スポンサーリンク