三次スプライン補間のプログラムを教えてください。
オリジナルでは対処できない部分が多々あり、vectorの処理がうまくできません。
よろしくお願いします。
いきなり「~のプログラム(アルゴリズムのことかな?)を教えて下さい」と言われても、
何をどう説明したものやら。
一から十まで、というのは掲示板の狭いスペースでは現実的ではありません。
それに情報が少な過ぎます。
「対処できない」、「うまくできない」といっても、それだけでは助言のしようがありません。
何がどううまくいかないかと、関連する追加情報を示して下さい。
例:
- 途中までソースを書いたが、分からないところがあり完成できない
→ その途中までのソースが必要。
- そもそもどうソースを書けばよいか全く手が出ない。
→ ……ごめん。掲示板で質問する以前に、もう少しC(or C++)とアルゴリズムについて勉強して欲し
い。
- ソースを書いたがコンパイルが通らない
→ 少なくともエラーが出る周辺のソースが必須。
- コンパイルは通ったが、結果が期待と異なる。
→ アルゴリズム全体のソース + 入力したデータ + 出力されたデータ + 期待する出力が必要。
- コンパイルは通ったが、実行時エラーで不正終了してしまう。
→ 上記の変形版。 アルゴリズム全体のソース + 入力したデータ + 出力されたデータ(あれば)
+ 期待する出力が必要。
これらの情報がなければ、仮に回答が付いたとしても、オリジナル(どこかの教科書か論文に載ってたのか
な)と
ほぼ同じ(→やっぱりうまくいかない可能性が高い)ものになると思います。
例えば、こんな感じに三次スプライン補間法へのポインタを示すだけ、とか(検索すればすぐに出てくるサ
イトですが)。
http://next1.cc.it-hiroshima.ac.jp/MULTIMEDIA/numeanal1/node16.html
これだと、ねこさんがすでに学習したことの繰り返しでしかないと思いますが……
アバウトすぎてすみません;;
一応、自分なりに作って見たものを載せてみます。
#includenrutil.h
#include<stdio.h>
#include<stdlib.h>
main()
{
FILE *fp;
fp = fopen(data.txt,r);
}
void spline(float x[],float y[],int n,float yp1, float ypn,float y2[])
{
int i,k;
float p,qn,sig,un,*u;
if (yp1>0.99e30)
y2[1]=u[1]=0.0;
else{
y[1]=-0.5;
u[1]=(3.0/(x[2]-x[1]))*((y[2]-y[1])-(x[2]-x[1])-yp1);
printf(%d,n);
}
for(i=2;i<=n-1;i++){
sig=(x[i]-x[i-1])/(x[i+1]-x[i-1]);
p=sig*y2[i-1]+2.0;
y2[i]=(sig-1.0)/p;
u[i]=(y[i+1]-y[i])/(x[i+1]-x[i])-(y[i]-y[i-1])/(x[i]-x[i-1]);
u[i]=(6.0*u[i]/(x[i+1]-x[i-1])-sig*u[i-1])/p;
}
if(ypn>0.99e30)
qn=un=0.0;
else{
qn=0.5;
un=(3.0/(x[n]-x[n-1]))*(ypn-(y[n]-y[n-1])/(x[n]-x[n-1]));
}
y2[n]=(un-qn*u[n-1])/(qn*y2[n-1]+1.0);
for(k=n-1;k>=1;k--);
y2[k]=y2[k]*y2[k+1]+u[k];
}
main2()
{
FILE *fr;
fr = fopen(dataneo.txt,w);
fclose(fr);
}
まだ、勉強しはじめたばかりで明らかな間違えがありそうなんですが…
vectorの処理でエラーが出るので、定義をわかっていないと思うのですが、もしよろしければ
よろしくお願いします。
エラーといわれても、どこで出てるのか、どんなエラーか
あなたにしかわからない・・・
ねこさんの示したソース内にvectorなるものが見あたらないのですが,
nrutil.hというのはひょっとして[Numerical Recipies in C]付属のやつでしょうか?
たしか[NRinC]のコードのvectorという関数で動的に確保した配列は
添え字を1から始まるように使わなければならなかったような記憶があります.
そのあたりに原因があったりはしないでしょうか.
見当違いだったらすみません.
> float p,qn,sig,un,*u;
>
> if (yp1>0.99e30)
> y2[1]=u[1]=0.0;
> else{
> y[1]=-0.5;
> u[1]=(3.0/(x[2]-x[1]))*((y[2]-y[1])-(x[2]-x[1])-yp1);
uをポインタとして宣言して、uが指すべき実体を確保せずに配列として使っていますね。きちんと
確保してあげましょう。もちろん解放もお忘れなく。
もし、y2もsplineに渡す前に領域の確保をしていないなら、こちらもあらかじめ領域を
確保しておく必要があります。
ところで、3次スプライン補完と言いつつ、出力がy2のみ?
3次多項式のそれぞれの係数(ただし、0次はyと同一なので残りの3つ)が必要だと思うのですが。
もひとつ。
> if (yp1>0.99e30)
> y2[1]=u[1]=0.0;
> else{
> y[1]=-0.5;
> u[1]=(3.0/(x[2]-x[1]))*((y[2]-y[1])-(x[2]-x[1])-yp1);
> printf(%d,n);
> }
else直後のy[1]=-0.5;って、y2[1]=-0.5;ではありませんか?
なお、この手の問題はxやyの宣言時にconstを付けていると一発で見つかります。
計算の内容については、VC++の話題としてはオフトピック気味なのでこれ以上はパス。