none
平面上の4点における双3次スプライン補間について RRS feed

  • 質問

  • 私は現在、Visual Studio 2008でアプリケーションの開発を行っています。

    平面にある4点のデータから3次元スプライン補間により、任意の位置でのデータを補間するプログラムを考えているのですが、なかなかうまくいきません。

    アルゴリズムを知っている方がいらっしゃいましたら、教えていただけないでしょうか。

    よろしくお願いいたします。

    2011年7月26日 20:28

回答

すべての返信

  • この投稿の結果、何を得たいのでしょうか。
    コードの実例を書いてほしいという意味合いなら、"C++" もキーワードに加えて検索すればでてきそうなものですけれども。

    うまく動かないなら、動かないものを提示するべきです。
    ただ、コードを全部貼り付けられると読み手が大変なので、きちんとポイントを押さえた質問にできると良さそうですね。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2011年7月26日 22:05
    モデレータ
  • 現在、1次元での3次スプライン補間ができています。

    例:
    (1, 100), (2, 200), (3, 300), (4, 400)
    X=1.5のとき、Y=150

    しかし、2次元となると、どのようなアルゴリズムになるのかが理解できません。

    もし可能でしたら、アルゴリズムやコードの実例などを書いていただけないでしょうか。

    よろしくお願いします。

    2011年7月26日 22:29
  • 外池と申します。

    「双3次スプライン補間」なら、NUMERICAL RECIPESにコードが載っています。古い版の「C」のコードであれば、無料で閲覧できます。
    http://apps.nrbook.com/c/index.html

     


    (ホームページを再開しました)
    2011年7月27日 0:50
  • お返事ありがとうございます。

    実はNUMERICAL RECIPESの本を見ているのですが、それでもよくわかりませんでした。

    1次元の場合、(0, 0), (1, 10), (2, 20), (3, 30)のようなデータで、Xが重なることはないと思います。

    しかし、2次元の場合では、(0, 0, 0), (1, 0, 10), (1, 1, 20), (0, 1, 30)のように、それぞれXとYが重なってしまいます。

    これをどう、処理させれば良いかわかりません。

    ちなみに、ライブラリとかはないのでしょうか。

    2011年7月27日 1:14
  • 外池です。

    NUMERICAL RECIPESを読んで判らないとなると・・・、ちょっと苦しいですね。ライブラリの有無をお尋ねになっていますが、要するに、双3次スプライン補間が「出来れば」よいのですか? それとも「理解」したいのですか?

    理解したいなら、NUMERICAL RECIPESを徹底的に読めば判るはずです。ざっとの考え方は、x方向にm点、y方向にn点のm×n点のデータがある場合、横方向(X軸方向m点の関数)の2階導関数を、縦方向(Y軸方向)にn列分も予め計算しておき(これでひとつのメソッド)、あと、縦方向(Y軸方向n点の関数)の2階導関数の計算と実際の補間操作を行う(もうひとつのメソッド)、というものです。繰り返し、多数の補間点の計算を行う場合、後者のメソッドだけ繰り返し呼べばOK。

    ところで、本当に4点のデータだけで双3次スプライン補間するんですか?

    というのも、上記の説明でお気づきかと思いますが、4点しかないデータのうち、例えば、お示し頂いている(0, 0, 0), (1, 0, 10), (1, 1, 20), (0, 1, 30)のうち、前者の(0, 0, 0), (1, 0, 10)の2点の間で2階導関数を求めるなんてナンセンスですよね? (2点しかデータがなければ、2階導関数はゼロ)

    そんなわけで、仮にライブラリが入手できたとして、根本的に、やろうとしていることに無理(というか無駄)があると思います。

    逆に、2階導関数がゼロでということを利用して、NUMERICAL RECIPESに載っているコードを単純化すれば良いのでは?


    (ホームページを再開しました)
    2011年7月27日 1:52
  • 双3次スプライン補間のプログラムを作成し、さらにできれば理解もしたいと思っています。

    >>本当に4点のデータだけで双3次スプライン補間するんですか?
    4点での補間を行おうと考えています。どの本にも、4点ではできないとは書いていなかったので、できると思っているのですが・・・。

    2階導関数がゼロについては、自然3次スプラインの場合では片方または両方の端点でゼロになるという条件があります。

    現在は、GSLライブラリにより、1次元3次スプライン補間ができています。
    1次元スプライン補間を2回行えば出来るようですが、やはり2次元になるとどう考えてよいのかわかりません。

    2011年7月29日 21:58
  • 外池です。C++の話題から既に大きく外れているので、回答はこれを最後とします。グラフ、というか、スケッチを描いて、ご自身が取り組んでおられる問題の数学的な側面をよく吟味してください。

    xの関数であるf(x)が、xとf(x)の数値のペアで(0, 0), (1, 10), (2, 20), (3, 30)と与えられているとして・・・、

    って、書き始めましたが、この貴殿が例示された数字を眺めて、今、気付きました。これって、f(x)=10xの直線(2階導関数f''(x)はいたるところでゼロ)じゃないですか? もちろん直線でもスプライン補間のプログラムを動かせますが、例示としてまったく不適切です。

    まぁ、いいでしょう。代わりに(0, 0), (1, -3), (2, 20), (3, -5)で与えられる凸凹した関数f(x)を考えましょう。この時、2階導関数f''(x)は計算できますし、計算する価値はあります。これは、x軸上にならんだ4点についてf(x)の値が与えられているケースです。

    次に、xとyの関数であるf(x,y)を考え、xとyとf(x,y)の値の組み合わせで(0, 0, 0), (1, 0, 10), (1, 1, 20), (0, 1, 30)と与えられているとしましょう。これは、xy平面状の正方形の四隅についてf(x,y)の値が与えられており、ねじれた曲面のようなものを表しています。しかし、この関数を双3次スプライン補間するとなると、先にご説明したとおり、まずは、(0,0,0)と(1,0,10)の2点間(yを0に固定して、x=0~1の間)で2階導関数を計算します。次に、(0,1,30)と(1,1,20)の2点間(yを1に固定して、x=0~1の間)で2階導関数を計算します。

    4点だけで与えられたf(x,y)の補間となると、出だしが、必ず、2点間の2階導関数の計算から始まることになります。2点間は、必ず直線で結ばれますので、いたるところで2階導関数がゼロであることは自明であって、スプライン補間の手法を使う必要はありません。直線で補間する操作を組み合わせれば出来てしまいます(しかも、これは、スプライン補間のプログラムを動かしたときと同じ結果になります。)

    もしx座標3点、、y座標3点の長方形をなす9点でf(x,y)が与えられているような場合なら、双3次スプライン補間をする価値はありますが・・・。

    ・・・・・・・・・追記・・・・・・・・

    関数f(x)の値が、f0=f(0)とf1=f(1)の2点だけで与えられているとします。直線で補間するしかなく、
        f(x)=(1-x) f0 + x f1
    と書けます。

    拡張します。

    関数f(x,y)の値が、f00=f(0,0)、f01=f(0,1)、f10=f(1,0)、f11=f(1,1)の4点で与えられているとします。そうすると、補間した結果は、
        f(x,y)=(1-x)(1-y) f00 + x(1-y) f10 + (1-x)y f01 + x y f11
    です。


    (ホームページを再開しました)






    2011年7月30日 0:07