スプライン補間でデータを計算した結果は異なる?正しい計算結果はどちら?

このQ&Aのポイント
  • x=[-1,0,1,2],y=[0,1,0,0]のデータで区間x=0~1をスプライン補間で計算させています。MuPADでcubicSplineを用いた場合とC言語によるアルゴリズム辞典から作ったソフトでは計算結果が微妙に異なります。
  • どちらが3次スプライン補間として正しいのかお教え願えないでしょうか?あるいはどちらも正しいとして、スプラインの種別が違うのでしょうか?非常に漠然としていますが、よろしくお願いします。
  • 「自分のツールだとこういう結果だった」というようなアドバイスでも大歓迎です。
回答を見る
  • ベストアンサー

スプライン補間

x=[-1,0,1,2],y=[0,1,0,0]のデータで 区間x=0~1 をスプライン補間で計算させています。 MuPAD でcubicSplineを用いた場合と C言語によるアルゴリズム辞典から作ったソフトでは計算結果が 微妙に異なります。 どちらが3次スプライン補間として正しいのかお教え願えないでしょうか? あるいはどちらも正しいとして、スプラインの種別が違うのでしょうか? 非常に漠然としていますが、よろしくお願いします。 「自分のツールだとこういう結果だった」というようなアドバイスでも大歓迎です。 X      MuPAD        C言語によるアルゴ 0      1            1 0.125  0.922851563  0.9488281 0.25   0.8203125    0.853125 0.375  0.698242188  0.7246094 0.5    0.5625       0.575 0.625  0.418945313  0.4160156 0.75   0.2734375    0.259375 0.875  0.131835938  0.1167969

質問者が選んだベストアンサー

  • ベストアンサー
  • shkwta
  • ベストアンサー率52% (966/1825)
回答No.2

x=[-1,0,1,2],y=[0,1,0,0] この3次スプライン補間を、次のように定義し計算しました。  (1)3次式で、節点での関数値はすべて一致  (2)2回微分可能で、導関数、2次導関数が連続  (3)両端 x=-1, x=2 で2次導関数が0 「'」は導関数、「"」は二次導関数です。 f1(-1)=0, f1(0)=1; f2(0)=1, f2(1)=0; f3(1)=0, f3(2)=0 f1'(0)=f2'(0); f2'(1)=f3'(1) f1"(-1)=0; f1"(0)=f2"(0); f2"(1)=f3"(1); f3"(2)=0 これを解くと、条件を満たす3次式f1,f2,f3は一組だけ存在し、 f1(x) = -0.6 x^3 - 1.8 x^2 - 0.2 x + 1 f2(x) = x^3 - 1.8 x^2 - 0.2 x + 1 f3(x) = -0.4 x^3 + 2.4 x^2 - 4.4 x + 2.4 区間[-1,0],[0,1],[1,2] にそれぞれf1,f2,f3を当てはめてつなぐと、2回連続微分可能な3次スプライン補間が得られます。 f2(x)の[0,1]での値は次のようになります。ご質問の「C言語によるアルゴ」に一致しているようです。ご所望のスプライン補間が、上記の定義と異なる場合は補足してください。 f2(0/8)=1 f2(1/8)=0.948828125 f2(2/8)=0.853125 f2(3/8)=0.724609375 f2(4/8)=0.575 f2(5/8)=0.416015625 f2(6/8)=0.259375 f2(7/8)=0.116796875 f2(8/8)=0

lachesis-r
質問者

お礼

大変明確な回答をありがとうございます。 私もただ今、他のアルゴリズム参考書で3次スプラインを検算させようとしています。 ただ、相当時間が掛かりそうですので、まずはお礼をのべておきます。 他にも情報があればお願いいたします。

lachesis-r
質問者

補足

補足します。 MuPADのcubicSplineの計算結果は、この4点を通る3次多項式と一致しているようです。 そのようなこともあるのかな?と思いましたが、3次スプライン補間の定義を考えると、なんとなく釈然としません。

その他の回答 (1)

  • FM-8
  • ベストアンサー率39% (65/164)
回答No.1

スプラインというのは,とびとびの点に対して, 滑らかにつながる曲線を補完する方法ですよね. 私の記憶では, 「指定された点をすべて通るもの」 と 「指定された点を必ずしも通らない」 いろいろなスプラインがあります. どちらのものか忘れましたが,「Bスプライン」というものがあります. 3次スプラインといえども,この2つはあると思います. その点はよろしいでしょうか? いろいろなスプラインがあるので, 市販のライブラリとの違いを論じる場合に, あなたが,アルゴリズムのコード化に失敗しているのか,もともとねらっている式が違うのかをまずは, 判断する必要があります. どのような補完をお望みですか? それは,3次式でよいのですか? 二次式ではだめなのですか? お望みの補完方法を明らかにした方が良い回答が得られると思います.

lachesis-r
質問者

お礼

早速の回答ありがとうございます。 今回は各点を通る事が大前提ですのでB-スプラインではないです。 次数は3次、始点・終点の境界条件は「自然条件」と呼ばれるもので2次微分係数は0です。 Cのコードは上記にあるように、間違ってはなさそうです。

関連するQ&A

  • スプライン補間

    スプライン補間 空間座標において,各点の座標( x(t),y(t),z(t) ) ( t:時間 )と速度ベクトル( u(t),v(t),w(t) )( u,v,w,はそれぞれx,y,z軸方向の速さ )がわかっている時,スプライン補間して各点の間の座標を知りたいのですが,スプライン補間には複数のスプライン関数があるようでどれを用いるのがベストなのかがわかりません.各関数の特徴,使用条件などを教えていただきたいです,

  • 3次スプライン補間法について

    x=3,7,4,7,5,8,3,2,3 (秒) Y=4,7,2,3,12,6,13,5,1,24 (cm) として、 速さa(cm/秒)はa=Y/xで出てくるのですが(a=1.7,1,0.5・・・)、 それぞれの点を結ぶと折れ線グラフになりますよね? 3次スプラインという補間関数を使うと、 それぞれの点を通過する滑らかな曲線を引けるらしいのですが、 この場合、x秒における速さaを求める計算式はどのようになるのでしょうか? a=? ご存知の方いらっしゃいましたらご教授・アドバイスよろしくお願い致します。

  • ダイアログベースの3次Spline補間のプログラム

    現在、Visual C++ 2008 Express Editionを使用して下に示すようなダイアログベースの3次Spline補間のプログラムを作成しています。 各節点間を等分割するほうはできたのですが、各区間を同一刻み幅で算出するほうが、なかなかできません。 どこをどうしたらいいかがさっぱりです。 以下にプログラムの一部(各区間を同一刻み幅で計算する部分)を示しますので、教えてください。 わからない点は、dnの配列に入ってくる分割数が合っているときと少ないときがあることです。プログラムの後に使用した入力データと、dnの中身を参考までに掲載します。 ============▼プログラムの一部=========== /* n:全点数(int), num:全節点数(int),xn,yn:節点(double型のarray),dX:全区間(xn[0]~xn[num-1])の刻み幅(double) * dn[]:各区間の分割数(int),xx,yy:Spline補間による点(節点を含む,double),x計算された補間点のx座標(double) Cub(double):3乗する関数,Sqr(double):2乗する関数,a[],b[],c[],d[]:3次Spline補間に用いる3次関数の各係数*/ //nの初期化 n =0; //テキストボックスから刻み幅を取得 dX = double::Parse(DX->Text::get()); //各区間の分割数を計算し、全点数を求める for(i=0;i<num-1;i++){ dn[i]=(int)((xn[i+1]-xn[i])/dX); n +=dn[i]; } //xx,yyを全点数+1(最後の節点を含むために+1をしている)で領域確保 xx=gcnew array<double>(n+1); yy=gcnew array<double>(n+1); //ループインデックスを初期化 i=0,j=0; //補間点のx座標を求めながらy座標を算出 for(x=xn[0];x<=xn[num-1];x+=dX){ if(!((xn[j]<=x)&&(x<xn[j+1]))){ j++; } if(i>n+1){ break; } xx[i]=x; yy[i]=a[j]*Cub(xx[i]-xn[j])+b[j]*Sqr(xx[i]-xn[j])+c[j]*(xx[i]-xn[j])+d[j]; i++; } =======▼入力データ(csvファイル)=========== xn yn 0.904 7.54 1.002 13.86 1.104 23.42 1.207 36.61 1.305 52.91 1.403 73.4 1.505 97 1.603 123 1.706 151.3 1.808 182.6 1.906 215.3 2.009 249.2 2.107 284.6 2.209 321.6 2.312 359 2.41 398.1 2.571 438.7 2.669 504.9 2.772 548.3 2.869 593 2.972 639 3.075 687 3.172 736 3.275 787 3.378 840 3.476 895 3.578 951 3.676 1011 3.779 1073 3.876 1136 3.979 1204 4.077 1276 4.18 1353 4.277 1440 4.38 1543 4.483 1762 4.585 2082 4.683 3445 4.786 5598 4.888 7120 4.991 8080 =======▼dnの中身=========== Excelでの計算値 プログラムでの計算値 --------------------------------------- 98 97 102 102 103 102 98 97 98 98 102 101 98 98 103 102 102 102 98 97 103 102 98 98 102 101 103 102 98 98 161 161 98 97 103 102 97 97 103 102 103 103 97 96 103 102 103 103 98 97 102 101 98 98 103 102 97 96 103 103 98 97 103 102 97 97 103 102 103 102 102 102 98 97 103 102 102 102 103 102 上の表の右側はダイアログ上で、「区間間隔」をクリック(各ラジオボタンをクリックすると右横のテキストボックスが入力できるようになります。)してテキストボックスに0.001を入れた時の結果です。

  • 線形補間について教えてください。

    今手元にx、y、zの座標が140個分あるのですが、それをエクセルの散布図を使いグラフにしました。しかし、明らかにおかしな場所に座標がプロットされていたりするため、スプライン補間などを使いきれいにしたいと考えています。 インターネットなどで、線形補間について調べたのですが、表現が難しくなかなか理解できませんでした。 スプライン補間やラグランジェ補間、ニュートン補間など色々あるようですが、これらの違いは何なのでしょうか。どなたか簡単に教えてください。お願い致します。 また、エクセルを使ったスプライン補間のやり方も教えてくだされば幸いです。 よろしくお願いします。

  • 二変数関数の補間

    いつもお世話になっております。 数値計算において、 f(x,y)という関数をx,yについて補間(3次スプライン)したいのですが、 高速に計算できる方法はありますでしょうか? 因みに計算は倍精度並の正確さが必要です。 numerical recipes in Cに載っているやり方を二次元に拡張しようと試みたのですが、途中で挫折しました・・・

  • 3次元曲面補間方法を探しています.

    3次元データの補間方法のアルゴリズムを探しています. 不均等にサンプリングした3次元データ(x,y,z)を基に曲面補間を行いたいと思っています. 最初に,zを一定の基で基準データ(x,y)を取得し,データを基に係数を算出します. システムは係数を用いて実際の取得データ(x,y)からzを補間したします. 現在のシステムは多項式で補間しています しかし,もっとメモリを食わず,精度のよい補間補法がないか探しています. 一応候補として考えたものはスプライン曲面と細分割による処理です. これらでは,問題点としてサンプリングした範囲を超えた(x,y)データでは補間ができないというものがあります.また,計算時間がかかるという問題点もあります. これらに限らず,よい方法はありませんでしょうか.

  • 単位円の方程式を3次スプライン補間で内挿するには

    三次スプライン補間でP(θ)と Q(θ)の内挿を求めたいです。 x(θ) = cosθ と y(θ) = sinθ 0≦θ≦2π N + 1 = 4、 8 、16 ここからどうやってPとQを求めればいいのでしょうか? 最終的にはPとQを求めて(P(θ)、Q(θ))の媒介変数を求めて 内挿で得られた値と実際の値との誤差をθの大きさでグラフ化したいのですが 単位円の方程式を内挿で求める事が出来ません。 単位円の方程式を3次スプライン補間で内挿するにはどうすればいいのでしょうか???

  • 補間曲線を関数で求める

    いくつかの離散的なデータに対する補間曲線を求めたいです。 また、その補間曲線を関数を用いて求めることを行いたいのですが、 分かるかたが居ましたら、具体的な方法について教えて頂けないでしょうか? 使用するデータは二次元のデータになり、総数としましては約10点程です。 具体的なデータは以下のようになります。 x y 22.5 672 27.5 491 32.5 331 37.5 269 ・ ・ ・ この様に続いているデータに対して 次数が2以上の曲線を関数で求めたいのです。 (例:3x^2+4x+3)。 スプライン曲線や重回帰法などを見ておりますが、 よく理解できません。 どうぞよろしくお願いします。

  • 教えてください

    本当にわかりません。教えてください、おねがいします 問題は (x,y)=(1,4),(2,3),(4,7),(6,2),(7,1)の5点を3次スプライン補間した結果得られるx=1.4,3.2,4.9,6.2におけるyの値を求めよ。 です

  • 検流計 補間法について

    補間法とは自然数xがx0,x₁,x₂….xnの値をとるとき、被変数yがそれぞれy0,y₁,y₂…ynの値をとることが知られている時、区間xpxq間の任意の値のxに対応するyの値を決定することである と図書館で見つけた本に記述されていたのですが、これをかみ砕いて言葉(文章)で説明するとどのようになるでしょうか?