- ベストアンサー
直線補間について
#define N 8 double x[N]={0,10,11,15,20,30,50,100}, y[N]={0, 0, 5,10,13,11, 8, 6}; といったデータ(実験で得られたデータです。)について任意のx座標tにおけるy座標を直線補間で求めたいのですが、この場合、0<t<10,10<t<11,......50<t<100と場合分けして直線の式を求める方法しか思いつかないのですが、この場合、実験で得られたデータの数の増減によってプログラムも毎回作り直さないといけないので困っております。もしこの方法以外に良い方法があれば教えてください。ソースも教えて頂けると有難いです。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
malloc() という関数があります. これは動的にメモリを確保する関数です. よく使います. これをつかうと,「Cらしいプログラム」になります. まず,データの数を入力して,それに見合うメモリを動的に確保します.そして,大きい順に並べ替えをして, あとは直線補間することになるでしょう. 下記の様なイメージでしょうか. デバッグしてないので,あくまでイメージです. int N; double *x,*y; fscanf("%d",&N); if((p1=malloc(N*sizeof(double)))==NULL){ fprintf(stderr,"can't allocate system memoey [%d]\n",N*sizeof(double)); exit(1); } if((p2=malloc(N*sizeof(double)))==NULL){ fprintf(stderr,"can't allocate system memoey [%d]\n",N*sizeof(double)); exit(1); } x=(double *)p1; y=(double *)p2; for(i=0;i<N;i++){ fscanf("%lf %lf",&(x[i]),&(y[i])); } sort(x,y);// データを大きさによってソートするルーチン // 直線補間ルーチン // 区間による場合分け. それでは.
その他の回答 (4)
プログラムを毎回作り直すというのはどういう意味だろう・・・ Nが定数か変数かに関係なく、インデックスを1つ求めるだけですよね。 for (i = 1; i < N; i++) { if (x[i] >= t) { break; } } /* この後、x[i - 1], y[i - 1], x[i], y[i]を使って直線補完する */ tの範囲が0~x[N-1]でない場合は少し工夫が必要ですが、解なし、もしくはy[0]かy[N-1]に張り付く。 Nが変数で、データをファイルから読み込むのであれば、No.1のFM-8さんの回答のようにするだけです。
お礼
わかりました。ありがとうございます。
- matyrcry
- ベストアンサー率47% (101/213)
似たような動作の直線近似機能クラスを設計したことがあります。 サンプルの座標を10個まで記憶できるようにして、サンプル個数 のパラメータを追加し、昇順にソートして使用しました。 サンプル数の上限を設定できるなら自動処理も楽です。 全体を挙げると大きいので検索のところだけ例示してみます。 typedef struct { int PrmSampMax; /* 補正サンプル数最大値 */ int nowSampMax; /* 現在サンプル有効数 */ int nowInput; /* 現在入力データ */ int nowOutput; /* 現在出力データ */ int InSamp[KINJ_SAMPMAX]; /* 入力サンプルテーブル */ int OutSamp[KINJ_SAMPMAX]; /* 出力サンプルテーブル */ } KINJ_CLASS ; // // 区間検索 // src:入力値 // no: 区間( ptr->InSamp[*no]~ptr->InSamp[*no+1]間 ) // static void KinjSampSearch( KINJ_CLASS *ptr,int src,int *no ) { int *iAdr,max; short i; max = ptr->nowSampMax - 2; iAdr = &(ptr->InSamp[1]); getNo = 0;look = 0; for( i = 0;i < max; ){ if( src <= *iAdr ){ break; } i ++; iAdr ++; } *no = i; return; }
お礼
なるほど、こういった検索をすればいいのですね。
- pacifist
- ベストアンサー率40% (4/10)
ごめんなさい、お手上げです。
- pacifist
- ベストアンサー率40% (4/10)
最小二乗法で直線を求めることができますが、記載されたデータであれば最小二乗法の次数を増やすか、スプラインを使われてはどうでしょうか。
お礼
ありがとうございます。グラフは曲線になるため、最小二乗法は使用する予定はありません。スプラインの場合はデータ数によって振動する場合があることと、x=0が続くとyの値が負になることがあり、これでは困るので、あえて直線補間にしようと考えたのですが、もし良い方法がありましたら教えて頂けますか?
お礼
ありがとうございます。やはり場合分けしかなさそうですね。