私は MATLAB 出身で、ずっと前に C から来た Python は初めてです。MATLAB で、川の土砂輸送をマルコフ過程としてシミュレートするスクリプトを作成しました。このコードは、指定された寸法の長方形の領域内にランダムな直径の円をランダムに配置します。円は不均一なサイズで、指定されたサイズの範囲からランダムに描画されます。円の配置操作を何回実行するかわからないので、while ループを使用してプロセスを完了します。よりコミュニティ指向になるように、MATLAB スクリプトを Python に変換しています。私はオンライン ツール OMPC を使用して作業を開始し、自動翻訳版から手動で作業を進めてきました (あまり役に立ちませんでしたが、これは当然のことです)。コードをデバッグするために、MATLAB で生成された結果を使用して一般的にPython の結果と比較対照します。スクリプトで計算が進むにつれて問題が発生するような方法で変数を宣言したことは明らかです。コード実行の異なるインスタンス間の一貫した問題の 2 つの例を次に示します。まず、スクリプトが次のような結果を返すため、コードは配列内の配列と思われるものを生成しました。
- array([[ True] [False]], dtype=bool)
この結果は、overlap_logix 操作で次のコード スニペットに対して生成されました。
CenterCoord_Array = np.asarray(CenterCoordinates)
Diameter_Array = np.asarray(Diameter)
dist_check = ((CenterCoord_Array[:,0] - x_Center) ** 2 + (CenterCoord_Array[:,1] - y_Center) ** 2) ** 0.5
radius_check = (Diameter_Array / 2) + radius
radius_check_update = np.reshape(radius_check,(len(radius_check),1))
radius_overlap = (radius_check_update >= dist_check)
# Now actually check the overalp condition.
if np.sum([radius_overlap]) == 0:
# The new circle does not overlap so proceed.
newCircle_Found = 1
debug_value = 2
elif np.sum([radius_overlap]) == 1:
# The new circle overlaps with one other circle
overlap = np.arange(0,len(radius_overlap), dtype=int)
overlap_update = np.reshape(overlap,(len(overlap),1))
overlap_logix = (radius_overlap == 1)
idx_true = overlap_update[overlap_logix]
radius = dist_check(idx_true,1) - (Diameter(idx_true,1) / 2)
変数についても、同じ実行で同様の結果が得られました。
- radius_check_update
- radius_overlap
- オーバーラップ_更新
動作中の MATLAB バージョンの同じコード スニペットを次に示します (要求どおり)。
distcheck = ((Circles.CenterCoordinates(1,:)-x_Center).^2 + (Circles.CenterCoordinates(2,:)-y_Center).^2).^0.5;
radius_check = (Circles.Diameter ./ 2) + radius;
radius_overlap = (radius_check >= distcheck);
% Now actually check the overalp condition.
if sum(radius_overlap) == 0
% The new circle does not overlap so proceed.
newCircle_Found = 1;
debug_value = 2;
elseif sum(radius_overlap) == 1
% The new circle overlaps with one other circle
temp = 1:size(radius_overlap,2);
idx_true = temp(radius_overlap == 1);
radius = distcheck(1,idx_true) - (Circles.Diameter(1,idx_true)/2);
Python バージョンでは、内容をより簡単に操作できるように、リストから配列を作成しました (コード スニペットの最初の 2 行)。配列結果内の配列とデータにアクセスするための配列の作成は、変数の型を間違って宣言したことを示唆していますが、よくわかりません。さらに、一部の変数には、たとえば (2L,) (円が配置されると数値次元が変化します) などのサイズがあり、2 番目の次元はありません。これは、サイズが (2L,1L) の別の配列で操作に配列を使用しようとすると、明らかな問題を引き起こします。これらの問題のために、私は配列の再形成を開始しましたが、1 つまたは複数の変数を間違って宣言したため、これらはハックであると判断したため停止しました。次に、同じ実行で次のエラーが発生しました。
- TypeError: 'numpy.ndarray' オブジェクトは呼び出し可能ではありません
操作の場合:
radius = dist_check(idx_true,1) - (Diameter(idx_true,1) / 2)
これは、上記のコード スニペットの下部にあります。自分でスクリプトを実行する方がおそらく便利なので、スクリプト全体を次のリンクに投稿しました。
https://github.com/smchartrand/MarkovProcess_Bedload
いくつかの初期パラメーター値で実行するようにコードをセットアップしたので、決定を下す必要はありません。これらのパラメーター値は、MATLAB ベースのスクリプトで期待される結果を生成します。プロットすると、次のようになります。
したがって、テスト値np.sum([radius_overlap])に応じて、151〜165行目の操作で特に問題が発生しているようです変数の型を間違って宣言したことが原因だと思いますが、よくわかりません。Python バージョンと MATLAB バージョンは、while ループの最初のステップまでの出力と、while ループの 2 番目のステップに入るコード 127 行目まで一貫していると自信を持って言えます。コードのこのポイントより下では、上記の文書化された問題により、最終的にスクリプトがクラッシュします。スクリプトの実行が 15% 完了する場合もあれば、5% に達しない場合もあります。これは、円の配置がランダムであるためです。私は Spyder (Python 2.7) IDE でコードを準備しており、研究の一環として作業コードを公開します。Pythonコーディングの間違いや誤用を特定するために提供できる助けをいただければ幸いです。