• ベストアンサー

直線補間について

#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と場合分けして直線の式を求める方法しか思いつかないのですが、この場合、実験で得られたデータの数の増減によってプログラムも毎回作り直さないといけないので困っております。もしこの方法以外に良い方法があれば教えてください。ソースも教えて頂けると有難いです。

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

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

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);// データを大きさによってソートするルーチン // 直線補間ルーチン // 区間による場合分け. それでは.

sawayakaimai
質問者

お礼

ありがとうございます。やはり場合分けしかなさそうですね。

その他の回答 (4)

noname#30727
noname#30727
回答No.5

プログラムを毎回作り直すというのはどういう意味だろう・・・ 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さんの回答のようにするだけです。

sawayakaimai
質問者

お礼

わかりました。ありがとうございます。

  • matyrcry
  • ベストアンサー率47% (101/213)
回答No.4

似たような動作の直線近似機能クラスを設計したことがあります。 サンプルの座標を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; }

sawayakaimai
質問者

お礼

なるほど、こういった検索をすればいいのですね。

  • pacifist
  • ベストアンサー率40% (4/10)
回答No.3

ごめんなさい、お手上げです。

  • pacifist
  • ベストアンサー率40% (4/10)
回答No.2

最小二乗法で直線を求めることができますが、記載されたデータであれば最小二乗法の次数を増やすか、スプラインを使われてはどうでしょうか。

sawayakaimai
質問者

お礼

ありがとうございます。グラフは曲線になるため、最小二乗法は使用する予定はありません。スプラインの場合はデータ数によって振動する場合があることと、x=0が続くとyの値が負になることがあり、これでは困るので、あえて直線補間にしようと考えたのですが、もし良い方法がありましたら教えて頂けますか?

関連するQ&A

  • 直線補間出来る関数

    直線補間できる関数はエクセルに有るのでしょうか? 直線補間とはxy座標において、点A(x1,y1),点B(x2,y2)が有ったときに、x1≦x≦x2における任意のxに対するyの値を点AB間が直線だと仮定して求めるすることです。 今は、VLOOKUP,match,Index関数を使ってやってますが、関数がある非常に楽です。

  • ラグランジュの補間法のCプログラム

    昨日学校でラグランジュの補間法の問題をC言語のプログラムで解けという課題が出されました しかし、友達と相談してもよくわかりませんでした 課題は以下の問題です sin関数6点、(0.92+0.01x)、x=0,1,2,3,4,5を求めて、ラグランジュの方法でsin(0.923)を計算せよ ちなみに答えは、0.79742です 先生からサンプルのプログラムをもらいました 以下のサンプルプログラムを参考にして解いてくださいと言われたのですが、どうしても解けません すいませんが分かる方、よろしくお願いします #include <stdio.h> #include <math.h> #define N 6 //データ数 double x[N]={ 0.0,1.0,2.0,3.0,3.1,5.0}; //X座標 double y[N]={0.0,1.1,2.5,4.0,4.1,5.0}; //Y座標 double lagrange( double); int main() { double xx,yy; //補間計算 printf("XX\t\tYY\n"); for( xx=0.0; xx<=5.0; xx+=.2 ) { yy = lagrange( xx); printf("%8.2lf\t%8.2lf\n", xx, yy ); } return 0; } //補間サブルーチン double lagrange( double xx ) { double z[N]; double yy=0.0; int i,j; for( i=0; i<N; i++ ) { z[i] = 1.0; //係数計算 for( j=0; j<N; j++ ) if( i!=j ) z[i]*=(xx-x[j])/(x[i]-x[j]); //補間値計算 yy+=z[i]*y[i]; } return yy; } 上記はあくまでサンプルプログラムなので、中に入っている数値は適当です よろしくお願いします

  • スプライン補間

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

  • 等高線図を書くための補間のやり方

    等高線図を書きたく,補間のやり方を調べています. 既知の点,P(x1,y1,z1),Q(x2,y2,z2),R(x3,y3,z3),S(x4,y4,z4)が存在したときに,これらの点に囲まれた中の任意の場所のz座標を補間法によって求めたいと考えています. 「補間」で検索をかけてみると,いろいろな補間方法がヒットしますが,x,y座標で,いくつかの点を曲線で結ぶというやり方はヒットするのですが,x,y,z座標については見当たりませんでした. まずは,有用な補間法の名前,複数ある場合は,それぞれ長所,短所などだけでも教えていただけませんでしょうか? よろしくお願いいたします.

  • Excelの補間について

    実験データを取り込んだエクセルのデータがあります。 以下の左がx軸で、右がyです。 time voltage 0.000 0.0000 0.001 0.0123 0.002 0.0374 2.000 0.0249 データは2000点あり、波形は正弦波など綺麗な形ではないです。 これに関して、もっとxの値を細かくし、yを補間したいのです。 たとえば上のxを1桁細かくしたデータを取りたいということです。 time voltage 0.0000 0.0000 0.0001 ? 0.0002 ? 0.0010 0.0123 2.0000 0.0249 というイメージです(?の部分を補間で求めたいです)。 データの補間は線形補間のような簡単なものでかまいません。 詳しい方、よろしくお願いいたします。

  • 実験データからの補間(パラメータ2つ)

    実験からインプット(x)とアウトプット(y)の回帰式(y=f(x))を求めます。 n個の異なる気温(T)で実験を行うと、n個の回帰式が作れます。 ここから、インプットと気温をパラメータとして y=g(x,T) といった関数を生成したいのですが、このような問題に対して数学の分野で 一般的に行われている方法はあるのでしょうか? (数学でなくても、解決法をご存知の方がいらっしゃればお願い致します) ひとつの気温に対するy=f(x)についてはデータが多いのですが、 n=5で、異なる気温での実験が少ないです。また、回帰式は3次多項式を使っています。 3次多項式係数の係数を次数ごとに補間してTの関数で表し、 y=a(T)x^3+b(T)x^2+c(T)x+d(T) としようかと考えたのですが、これは正しいのでしょうか?

  • 直線の方程式 難

    直線の方程式 難 次のような直線の方程式を求めよ。 (1)点A(1、2、3)を通り、@d=(2,3,-4)に平行 Oは原点、P(x、y、z)を直線上の点、tを実数とする。 @OP=@OA+t@dであるから(x,y,z)=(1,2,3)+t(2,3,-4) よってx=1+2t,y=2+3t,z=3-4t 教えてほしいところ まず、なぜこれが点A(1、2、3)を通り、@d=(2,3,-4)に平行な直線であるといえるのか理解できません。 x=4という直線を考えます。このxとはxy平面上に存在する無数の点(x、y)のx座標は4ということですよね?? ですから、それを満たすような座標を全て打てばそれが直線です。 ではx=1+2t,y=2+3t,z=3-4tの直線を考えます。このx、y、zは無数の点(x、y、z)の条件とは考えられません。 なぜなら、このx、y、zというのは終点座標(x、y、z)だからです。なので、xyz平面上の点のx、y、zの関係式ではないので xyz空間上に満たすような座標を打つことができない。よって、x=1+2t,y=2+3t,z=3-4は直線とはいえないないのでは??

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

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

  • X-Y1-Y2円弧補間

    お世話になります。 X軸が主軸になり 垂直に取り付けた2つのY軸 Y1軸、Y2軸 とあります。 例えば ①X-Y1がR=100 ② X-Y2がR=400 X軸はCW方向のみ移動しかできないものとする。 それぞれ円弧補間が必要で主軸のX軸は共通です。 これが実現できる モーションコントローラはありますでしょうか? PLCサーボシステム、PCボードなど 。 若しくはX軸をピッチ送り(0.1mmなど)して それぞれのY座標を求めて 直線補間する方法が 一般的でしょうか?? よろしくお願い致します。m(__)m

  • エルミート補間

    θが[0,2π]の範囲で P(θ) とQ(θ) をそれぞれ エルミート補間でx(θ) = cosθとy(θ) = sinθから求めたいです。 N + 1=4,、8、16で三つの場合に分けて求めたいのですが、どうすればいいのでしょうか?Nが変わると何をθの範囲を4等分、8等分、16等分と分けて補間するのでしょうか? N+1=4 N+1=8 N+1=16でそれぞれどのように式は変わってくるのでしょうか?