2D関数を適応的にサンプリングするための簡単な方法は何ですか?


22

値をサンプリングしたい2次元関数あります。この関数は計算が非常に高価であり、複雑な形状を持っているため、最小数のサンプルポイントを使用して、その形状に関する最も多くの情報を取得する方法を見つける必要があります。f(x,y)

これを行うにはどのような良い方法がありますか?

私が今まで持っているもの

  • 関数値をすでに計算している既存のポイントのセットから開始します(これは、ポイントの正方格子などです)。

  • 次に、これらのポイントのドロネー三角形分割を計算します。

  • ドローネ三角形分割において2つの隣接点が十分に(ある場合)と十分にそれらの関数値が異なる(> Δ F)、私はそれら挟ん新しい点を途中で挿入します。隣接する各ポイントペアに対してこれを行います。>バツ>f

この方法の何が問題になっていますか?

まあ、それは比較的うまく機能しますが、これと似た機能では、サンプルポイントがリッジを「飛び越える」傾向があり、そこに気づかないこともあるため、理想的ではありません。

Mathematicaグラフィックス

次のような結果が生成されます(初期ポイントグリッドの解像度が十分に粗い場合)。

Mathematicaグラフィックス

上記のプロットは、関数値が計算されるポイント(実際にはそれらの周りのボロノイセル)を示しています。

Mathematicaグラフィックス

上記のプロットは、同じ点から生成された線形補間を示し、それをMathematicaの組み込みのサンプリング方法と比較します(ほぼ同じ開始解像度)。

それを改善するには?

ここでの主な問題は、私の方法が勾配に基づいてリファインメントポイントを追加するかどうかを決定することだと思います。

改良点を追加するときは、曲率または少なくとも2次導関数を考慮することをお勧めします。

質問

ポイントの位置がまったく制約されていない場合に、2次導関数または曲率を考慮するための非常に簡単な実装方法は何ですか?(開始点の正方格子は必ずしも必要ではありません。これは理想的には一般的なものでなければなりません。)

または、最適化された方法で絞り込み点の位置を計算する他の簡単な方法はありますか?

これをMathematicaで実装しますが、この質問は主にメソッドに関するものです。「実装しやすい」ビットについては、私がMathematicaを使用していると見なされます(つまり、これはDelaunayの三角形分割を行うためのパッケージがあるため、これまでは簡単でした)

私はこれをどのような実用的な問題に適用していますか

相図を計算しています。複雑な形をしています。ある地域ではその値は0であり、別の地域では0と1の間です。2つの地域間で急激なジャンプがあります(不連続です)。関数がゼロより大きい領域では、滑らかな変動といくつかの不連続性の両方があります。

関数値はモンテカルロシミュレーションに基づいて計算されるため、不正確な関数値またはノイズが予期される場合があります(これは非常にまれですが、多数のポイントでは定常状態に到達しない場合などに発生しますいくつかのランダムな要因)

すでにMathematica.SEでこれ尋ねましたが、まだプライベートベータ版であるため、リンクできません。ここでの質問は、実装ではなくメソッドに関するものです。


@sukiへの返信

これは、あなたが提案する分割のタイプ、つまり、三角形の中央に新しいポイントを置くことですか?

Mathematicaグラフィックス Mathematicaグラフィックス Mathematicaグラフィックス Mathematicaグラフィックス

ここでの私の懸念は、領域のエッジで特別な処理が必要なように見えることです。そうしないと、上記のように非常に長くて非常に細い三角形が得られます。これを修正しましたか?

更新

私が説明する方法と、三角形に基づいて細分割を行い、三角形内に細分割ポイントを配置するという@sukiの提案の両方に現れる問題は、不連続がある場合(私の問題のように)、ステップの後にドローネ三角形分割を再計算することです3つの頂点で異なる関数値を持つ三角形が変更され、おそらくいくつかの大きな三角形が表示されます。

以下に2つの例を示します。

ex1 ex2

最初の例は、真っ直ぐな不連続の周りでサンプリングしたときの最終結果を示しています。2番目は、同様のケースのサンプリングポイント分布を示しています。

これを回避する簡単な方法は何ですか?現在、私は単純に再三角形分割後に消えるそれらのエーグを細分化していますが、これはハックのように感じ、対称メッシュ(正方形グリッドなど)の場合にはいくつかの有効なDelaunay三角形分割があるため、エッジが変更される可能性があるため、注意して行う必要があります再三角測量後、ランダムに。


この問題に関する新しい開発はありますか?
アンドレイ14年

回答:


10

私はしばらく前にこれに似た問題に取り組みました。

実装間の主な違いは、エッジではなく三角形に基づいてポイントを追加する場所を選択していたことだと思います。また、エッジではなく三角形の内側に新しいポイントを選択します。

古いポイントから新しいポイントまでの平均距離をわずかに増やすことで、三角形の内側にポイントを追加するとより効率的になると感じています。

とにかく、エッジの代わりに三角形を使用することのもう1つの良い点は、この特定のエッジに沿った勾配ではなく、勾配ベクトルの推定値を提供することです。

私のmatlabコードでは、いくつかの抽象メソッドを使用して、基本クラスを使用してほとんどの機械を処理しました。

  • weight(self) 三角形を次に分割する優先順位を決定します。
  • choosePoints(self,npoints = "auto") 各三角形の重みに基づいて評価する新しいポイントを決定します。

このセットアップは非常に柔軟であることがわかりました。

  • サブクラスのweight()関数を三角形の領域に設定すると、一定のメッシュ密度が生成されます。
  • weight()関数の平均値に三角形の面積を掛けて計算するように設定すると、一種の準ランダムな確率サンプリングが得られます。
  • 使用var(triangle.zs)することで、バイナリ出力を持つ関数に対して、二分探索を1次元以上に一般化できると感じています。
  • 使用area + var(triangle.zs)は、どこにでも一定の密度を配置するのに非常に効果的であり、あらゆる勾配に沿って密度を増加させました(ほぼ現在のもの)。

z値の分散を使用して、傾斜ができるように分散が無限にならないため、1次効果(傾斜)の重要性を近似しました。

最後の例では、低い値のスペースで高い値の不連続なブロブを検索していたため、背景密度は良好でした。それはゆっくりとメッシュ全体を埋めうとするとき、それはので、私は勾配に入れ、高重量のすべての方法の周りのブロブのエッジを以下に専念うブロブを見つけるだろう(そしてそれが唯一トップに充填するようにn三角形各反復で)。最後に、結果の背景メッシュ密度より大きいサイズの(合理的な形状の)ブロブ(またはブロブの穴)がないことがわかりました。

あなたが私の結果でいくつかの悪い点を取得したように、それらは私にとって問題ではありませんでした。なぜなら、あなたが近くの点を再実行すると、おそらく正しい答えを与えるようなエラーだったからです。私はちょうど悪い点の周りにメッシュ密度が増加するブリップになってしまうでしょう。

あなたが何をするにしても、三角形のサイズに関連する重みを作成することを常にお勧めします。そうすれば、他のすべてが等しい場合、最初に大きな三角形が分割されます。

たぶんあなたのための解決策は、私のアプローチをさらに一歩進め、その三角形のセルの内容に基づいて三角形を評価する代わりに、その1つおよび3つすべての隣接する三角形に基づいて評価することです。

これには、完全なヘッセ行列の推定値を取得するのに十分な情報が含まれます。z = c1*x + C2*y c11*x^2+c12*x*y+c22*y^2目的の三角形のすべての頂点に対して最小二乗近似を行うことで取得できます(最初に三角形の座標系を中心に配置します)。

勾配やヘッセ行列(これらの定数)は、不連続で無限大になるため、直接使用しません。

多分、それらの点の平面近似に対するz値の二乗和誤差は、2次効果がいかに興味深いかを示す有用な尺度になるでしょう。


更新しました:

それは私には合理的に見えます。

私は実際にエッジを特別なケーシングにしたことはありません。それは少し気になりましたが、私がやっていたことについては、エッジの周りの多くのポイントから始めるだけで十分でした。

よりエレガントな方法は、エッジと三角形の重み付けという2つのアプローチを組み合わせることです。次に、エッジが長すぎる場合は、半分にカットします...コンセプトがより高い次元に一般化する方法が好きです(しかし、数値は速くなります)...

しかし、メッシュの本体に高アスペクト比の三角形があるとは思わないため、Matlabの自由境界関数などの関数を使用して境界を見つけ、境界上の1次元少ない次元で同じアルゴリズムを実行できます。たとえば、キュ​​ーブ上で正しく実行すると、エッジ、面、キューブ内で同じメッシュ密度を得ることができます。面白い。

私が良い解決策を見つけられなかった1つのことは、私のバージョンが初期ポイントセットの凸包の外側を探索しないという事実でした。


最初に三角形を使用することも考えましたが、最初にいくつかの技術的な問題があり(それ以来解決しました)、後で三角形を使用する方がずっと良いとは思いませんでした。質問:新しいポイントはどこに置きますか?三角形の真ん中に?非常に長くて細い三角形ができると予想していたので、これをしませんでした。あなたがしたことを理解した内容で投稿をすぐに更新します。
サボルクス

私の編集を見て明確にしてくれますか?
ザボークス

どんな種類の細分割スキームを使用しても、エッジが避けられない特殊なケースであることがわかります。私の場合、エッジに垂直に高い勾配がありますが、エッジに平行ではありません。これは、エッジを特別なケースにしないと物事が非効率的になります。
サボルクス

私が見つけた別の問題は、頂点の関数値が異なる場合に、再三角形分割により大きな三角形が時々表示されることでした。:私はこのようなものになってしまったi.stack.imgur.com/nRPwi.pngは直線補間密度プロットである、とi.stack.imgur.com/208bP.pngは、サンプリングポイント(まったく同じではない)です。これは、まっすぐなエッジに沿った単なる不連続です。この問題にぶつかりましたか?はいの場合、どのように解決しましたか?細分化の各ステップの後に、完全に再三角測量しましたか?
ザボルクス

ここで三角測量が本当に何を意味するのかわかりません。評価した各ポイントは、あるポイントでの関数の値なので、メッシュフリーの方法で使用するようなことをしてみませんか?en.wikipedia.org/wiki/Smoothed-particle_hydrodynamicsまた、この方法で微分を推定することもできます...
meawoppl

0

ヒューリスティックの主な問題は、1次元の勾配のみを考慮しているため、dfdxは小さいがdfdyが大きい領域(例の中央にあるように)で、見ているときにポイントを見落とすことだと思います「間違った」次元で。

1つの簡単な解決策は、4点のセットを検討し、それらの重心を取り、| dfdx | + | dfdy |を近似することです。これらの4つのポイントを使用します。もう1つの方法は、3つのポイント(三角形)を取り、それらの上の表面の最大勾配を取ることです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.