• ベストアンサー

テイラー展開(C言語)

こんにちは<_ _> 毎度もうしわけありません・・・ exp(x)をテイラー展開を用いて計算せよという問題で -----------------------外を与えられ サイトなどを見て見よう見まねで-----内を組んでみましたが 当然思い通りになるわけでもなく;; テイラー展開という考え方は1.00007の何乗を1と.00007分に分けて 計算するというものであるという認識です。 (そもそも言葉自体始めて見て、サイトで調べてみたもので あっているかどうかも・・・) 以下の結果 「 x myexp(x) exp(x) 0.0 1 1 10.0 110123 22026.5 20.0 4.85165e+009 4.85165e+008 30.0 1.60297e+014 1.06865e+013 40.0 4.70771e+018 2.35385e+017」 こうなりましたが、期待の結果はexpとmyexpの結果が 同じものにならなければいけないみたいです・・・ テイラー展開の補足とヒントでもいいので プログラムの組み方を教えてください<_ _> おねがいします<_ _> #include<stdio.h> #include<math.h> double myexp(double); int main(void) { double x; printf(" x myexp(x) exp(x)\n"); for(x=0;x<=40;x=x+10) printf("%5.1f%14.6g%14.6g\n",x,myexp(x),exp(x)); } double myexp(double x) { double EPS=1e-08; double s=1.0,e=1.0,d=1.0,diff; int k; ----------------------------------- d=x*x; k=2; while (1){ x = x*d; s *= (k-1)*k; k += 2; diff = x/s; /* n項目の値 */ e += diff; if (fabs(diff) < EPS){ break; } } return e; ------------------------------ }

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

> 理数系はあまり勉強してませんでした。 > > 問題は新卒研修の提出問題で > その問題を解いている段階です・・・ あらまそれは大変ですね。 わたしはテイラー展開(マクローリン展開)は大学の 情報関係の講義でやったので、純粋な文系だとやらないかもしれませんね。 提出問題だということなのでもうちょっと悩んでもらうとして、 テイラー展開ってのは何かというと、 ある式(今回の問題だと e^x ですね)を、ちょっと単純にした式の総和にするということです。 で、この「単純にする」のに微分を使います。 ある式 f(x) があったときに、 f'(x) (f(x)を一回微分したもの) + f''(x) (f'(x)をさらに一回微分したもの)+ f'''(x) (f''(x) をさらにもう一回微分したもの) … と、微分をし続けながらそれらの合計により元の式の値(の近似)が求まるわけです。 元の式によって何回微分ができるとか、どのくらいの精度で近似を求めるとか ありますが、今回の e^x は何回でも微分できますので、 単純にどこまで細かくするかの問題になります。 で、e^x をテイラー展開するとWikipediaにもあるような式になります。 #なんで、というのは数学カテゴリでお訊きください。 #わたしにはわかりやすく説明できる自信がありません。 で、それをプログラムで書くと #2の方の回答にある myexp( x ) = 1 + x + (x^2/2!) + (x^3/3!) + (x^4/4!) + ....... + (x^n/n!) になります。 大まかに書くと n=0 合計=0 while (1) { 1. nの階乗を求める(n!) 2. xのn乗を求める(x^n → pow(x, n)) 1. / 2. の値を求める 1. / 2. が十分小さかったらループから抜ける 合計に1. / 2. を足す n を1増やす } こんな感じです。 ちょっとサービスしすぎたような気がしないでもないですが、乗り切ってください。

その他の回答 (5)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.6

締め切りによっては本なんか読んでいるひまもないかもしれませんが、 図解入門 よくわかる微分積分の基本と仕組み http://www.cbook24.com/bm_detail.asp?sku=4798010405 この本なんかは理解の取っ掛かりになるかもしれません。 #でもAmazonのレビューで点数良くないな… あと、#5での説明はわかりやすくしようとして 正確にでない説明になっているところがあるかもしれないので、 気になるようでしたらやはりその方面の資料を 一回あたっておくことをお勧めします。 今月末ぐらいなら結城浩さんの新刊が出る予定なので それを勧めるのですが。 #ちょうど関連する分野の本です

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★アドバイス ・『テイラー展開』よりも『マクローリン展開』で検索した方が良いかもしれませんよ。  あと『科学技術計算』をキーワードで検索します。  すると  http://www5.airnet.ne.jp/tomy/cpro/csource.htm→『技術計算用Cプログラム ソース』  というサイトが発見できます。  こちらのサイトは私も以前から参考にさせてもらっていたサイトです。  2000年~2001年の時にお世話になりました。  バグが一部あるとその後に書かれていましたが、今見たら消えています。  多分直したのかもしれません。未確認ですが。 ・それでこのサイトの  http://www5.airnet.ne.jp/tomy/cpro/mp8.htm→『MPAライブラリ 指数・対数・べき乗関数ルーチン』  が参考になりませんかね。  記述はこのサイトで紹介している多倍長演算の関数群で書かれているので <math.h> にある  算術関数に置き換えれば良いでしょう。 ・下の『参考URL』にマクローリン展開の分かりやすいサイトを張っておきます。  『指数関数のマクローリン展開』にある数式を C 言語を用いてループで記述すれば出来ます。 ・以上。

参考URL:
http://assam.cims.hokudai.ac.jp/~josch/workshop/math/Maclaurin/Maclaurin2.htm
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

質問者さんの年齢や学歴が分かりませんが... ご自身でも書かれているように、やはり数学を復習した方が近道だと思います。このまま強引にすすめても、指数関数はできても三角関数だとできないということになりそうです。 テイラー展開そのものは高校では習わなかった気がしますが、級数や微分なら(普通科や工業科の)高卒程度の学力で理解できるはずです。そこを確実に押さえておけば、テイラー展開の説明を読めば難しくないでしょう。

hisetu_001
質問者

お礼

当方大卒の新社員です。大学は私立文系で 高校は理数科でしたが、転向して文系にいくことを決めていたので 理数系はあまり勉強してませんでした。 問題は新卒研修の提出問題で その問題を解いている段階です・・・

  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

私も検索してWikipediaのページを見ましたが?でした http://assam.cims.hokudai.ac.jp/~josch/workshop/math/Maclaurin/Maclaurin1.htm をみてようやくマクローリン展開は理解できたつもりです。 質問の関数ですがWikipediaにも書いてある指数関数のテイラー展開から myexp( x ) = 1 + x + (x^2/2!) + (x^3/3!) + (x^4/4!) + ....... + (x^n/n!) をCで書けばよいようです。 実際は無限回続きますが n > xになると(x^n/n!)はしだいに小さくなるので(x^n/n!)がEPS=1e-08以下になった時点でループを抜ければよさそうです。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

テイラー展開をキーワードにGoogleで検索すると Wikipediaのページがトップにくると思うんですが、 そこをみて > テイラー展開という考え方は1.00007の何乗を1と.00007分に分けて > 計算するというものであるという認識です。 と思われたわけではないですよね? 少なくとも今回はそのとらえ方は違います。 そして、myexpの中身が間違っています。 テイラー展開 - Wikipedia http://ja.wikipedia.org/wiki/%E3%83%86%E3%82%A4%E3%83%A9%E3%83%BC%E5%B1%95%E9%96%8B の指数関数と自然対数のところにある式を素直に使えばいいんじゃないでしょうか。 スピードだのなんだのは正しい答えが求まるようになってから。 myexpを適当に書き直したところ x myexp(x) exp(x) 0.0 1 1 10.0 22026.5 22026.5 20.0 4.85165e+008 4.85165e+008 30.0 1.06865e+013 1.06865e+013 40.0 2.35385e+017 2.35385e+017 こんな感じになりました。

hisetu_001
質問者

お礼

解答ありがとうございます<_ _> 私は http://www.tohtech.ac.jp/~comms/nakagawa/taylorexp/taylor1.htm を参考に見ていました。 wikiのもみましたが数式が読み取れず言葉も難しくて・・・orz 数学を勉強するところから始めたほうがいいのでしょうか・・・

関連するQ&A

  • C言語で表記についの質問です

    C言語です。 exp(x)のテイラー展開を数値計算で求めるプログラムですが、 プログラムでは相対打ち切り誤差をEPSと定義しています。 具体的には double myexp(double x){ double EPS=1e-08; double s=1.0,e=1.0,d; int k; for(k=1;k<=200;k++){ d=s; e=e*x/k; s=s+e; if(fabs(s-d)<EPS*fabs(d)) return s; } と上の様に書かれています。 わからない点は上記のプログラムでEPS=1e-08のeは10の意味をしているでしょうか?EPS=10^-8理解 してよろしいでしょうか? またEPSのeと二つ目のe=1.0は全く異なるものでしょうか。 ご教授よろしくお願いします。

  • テイラー展開のプログラムについて

    テイラー展開のプログラムについて テイラー展開のプログラムについて プログラミングはまだ始めたばかりですが、宿題がいきなり出されました。 指数関数をテイラー展開する際に次のプログラムがありましたが、これを表している意味がよく分かりません。 (1)EPSとは??(2)Tnnは何?(3)format('EXP(', f10.5, ') ')の「10.5」は何か? ここら辺が特によく分かりません。 また、同じようにsinxや対数関数でテーラ展開のプログラムのとき気をつけなくちゃいけない点なども教えていただければ嬉しいです。   subroutine expotn (x) c   real Tn, ans, err   integer n c   EPS = 1.0e-6   n = 0   Tn = 1.0   ans = Tn   write(6,10) x 10 format('EXP(', f10.5, ') ') 50 if( abs(Tn) .gt. EPS) then n = n + 1 Tn = Tn * x / n ans = ans + Tn err = ans - exp(x)   write(6,11) n, ans, err 11 format(I3,' exp(X) = ',f12.7,' err = ',f15.10) go to 50 end if write(6,*) ' Exp( ',x,' )= ',ans return end

  • C言語 ニュートン法

    何をすればいいかよくわからなくて躓きました わかる方どうかお願いします 問 以下に示すプログラムで、x1 = x0 - f (x0) / f '(x0)を用いて、方程式の左辺関数 f (x) (= x 2 - a ) およびその導関数 f '(x) を独立させろ。 入力変数 a はグローバル変数としてよい。 導関数 f '(x)はプログラム内ではdfと表記することとする。 また、適切なコメントも追加すること。 /* newton.c: ニュートン法 */ #include <stdio.h> // printf, fprintf, fgets, sscanf #include <math.h> // fabs double newton(double x, double (*f)(double), double (*df)(double), double eps) {   int n;   double a = 0, x, x0, err, eps = 1.0e-10;   printf("# n, x, err\n");   printf("%4d, % .15e\n", n, x);   do {     n++;     x0 = x;     x = (x0 + a/x0) / 2;     err = fabs(x-x0);     printf("%4d, % .8e, % .8e\n", n, x, err);   } while (err > eps);     return x; } int main(void) {    double a = 0, x, x0, err, eps = 1.0e-10;    char s[128];   fprintf(stderr, " a = "); fgets(s, 128, stdin); sscanf(s, "%lf", &a);   while (a <= 0.0) {    fprintf(stderr, "'a' には正の数を入れてください。\n");   fprintf(stderr, " a = "); fgets(s, 128, stdin); sscanf(s, "%lf", &a);   }   x = (a + 1.0) / 2.0;   printf("\n# sqrt(%e) = % .15e\n", a, x);    return 0; }

  • テーラー展開について

    テーラー展開を用いて指数関数を多項式にしたいのですが、 f(x) = EXP(x) = 1 + 1 / 1! * x + 1 / 2! * x^2 + … というのは理解しているのですが f(x,y) = EXP(x + y)といった2変数の場合のテーラー展開やり方がわかりません。 一体どうのようにすればいいのでしょうか?

  • 微分演算子があるテーラー展開

    こんにちは.宜しくお願いいたします. いま,微分演算子をDとします.つまり,Dx(t)=dx(t)/dtの意味です. ただし,x(t)はxが時間tの関数. 下に出てくるsも時間記号で,s≧t. ここで, X=0で,exp(x)のテーラー展開は,ふつうに exp(x)=1+x+(x^2)/2!+・・・・です. そこで, (s-t)D=0で,exp[(s-t)D]のテーラー展開は, exp[(s-t)D]=1+(s-t)D+[(s-t)^2*D^2]/2!+・・・・となります. ここまではよしとしますが, よって, exp[(s-t)Dx(t)]=x(t)+(s-t)Dx(t)+{[(s-t)^2*D^2]/2!}*x(t)+・・・・ ∴ =x(t+s-t)=x(s) ←ここのx(t+s-t)になるのが分かりません. 数学通の方,宜しくお願い致します.

  • C++を使ってのテイラー展開

    C++を使って,sinとcosのテイラー展開をしたいのです。 プログラムを作ってはみたのですが,こんな感じでよろしいのでしょうか? #include<stdio.h> int main(void) {  int i,n;  double xb,x,sinx=0,cosx=0,hu;  xb=1.0;  hu=1.0;  printf("どこまで計算しますか?");  scanf("%d",&n);  printf("xはいくらですか?(1以下!)");  scanf("%lf",&x);  for(i=1;i<n;i++)  {  xb=xb*(x/i);  if(i%2==0)  { sinx=sinx+(hu*xb); hu=hu*(-1.0); }  else  { cosx=cosx+(hu*xb); hu=hu*(-1.0); }  }  if(i%2==0)  { printf("答え:%f\n",sinx); }  else  { printf("答え:%f\n",cosx); }  return 0; }

  • テーラー展開について

    テーラー展開について f(x)=exp(1/x)(x>0),0(x≦0) (1)x=0のとき、C∞であることを確認せよ。 (2)f(x)がx=0のまわりでテーラー展開不可能であることの証明

  • c言語プログラミングについて

    ニュートン法でx^2-2の根を初期値2、試行回数を200回までで求めるプログラムを作成しているのですがうまくいきません。 どなたかご教授お願いいたします。 #include<stdio.h> #include<math.h> int main() { int i; int N = 200; double x = 2.0; double xnew; double eps = 1e-16; for (i = 0; i < N; i++) { xnew = x - ( x * x - 2.0 ) / 2.0 * x; if (fabs(x - xnew) < eps) break; x = xnew; } printf("x=%.20lf\n", xnew); return(0); }

  • C言語の質問です

    ニュートン法のプログラムを組んだのですがPAD図が描けなくて困ってます どなたか回答お願いします /* newton.c: ニュートン法 */ #include <stdio.h> // printf, fprintf, fgets, sscanf #include <math.h> // fabs double a;    //グローバル変数 double f(double x)  //fは関数f(x) { return x * x - a; //f(x)=x~2-a } double df(double x)  //dfはf(x)の導関数f’(x) { return 2 * x; //df(x)/dx = 2x } double newton(double x, double (*f)(double), double (*df)(double), double eps) { int n = 0;     //初期化 double x0, err;    //x0は初期値 printf("# n, x, err\n"); printf("%4d, % .15e\n", n, x); do { n++; x0 = x; x = x0 - f(x0) / df(x0); //切片でy=0、x=x1 err = fabs(x-x0); printf("%4d, % .8e, % .15e\n", n, x, err); } while (err >= eps); return x; } /*メインルーチン*/ int main(void) { double x, eps = 1.0e-10; //収束条件 char s[128]; fprintf(stderr, " a = "); fgets(s, 128, stdin); sscanf(s, "%lf", &a); while (a <= 0.0) { fprintf(stderr, "'a' には正の数を入れてください。\n"); fprintf(stderr, " a = "); fgets(s, 128, stdin); sscanf(s, "%lf", &a); } x = (a + 1.0) / 2.0; x = newton(x, f, df, eps);   //ニュートン法の実装 printf("\n# √(%e) = % .15e\n", a, x); return 0; }

  • C言語のプログラム

    C言語で2つの微分方程式をEuler法、Heun法、Runge-Kutta法により求めるプログラムを作りたい。ただし、初期条件はx=0,y=1とする。また、間隔Δxを変えたときの解の変化を調べたい。 Euler法のプログラムはどうにか分かったのですが、Heun法、Runge-Kutta法のプログラムがわかりません。 Euler法のプログラム #include_<stdio.h> #include_<math.h> int_main(){ __double__a=0; __double__b; __int_____m=10; __int_____n; __double__h; __double__x,y; __double__dydx; __int_____k; __double__e; __double__f; __printf("オイラー法計算例:y=e^x,_y=1/e^4x\n\n"); __//_y_=_e^x __b_=_1; __for(n=100;n<=10000;n*=100){ ____h_=_(b-a)/n; ____printf("y'_=_y:_h(=dx)_=_%.1e_(y=e^x)\n",h); ____x_=_a;_y_=_1; ____for(k=0;k<=n;k++)_{ ______x_=_k*h; ______if(k%(n/m)==0)_{ ________f_=_exp(x); ________e_=_fabs(y-f); ________printf("x=%.2f,_y=%f,_e^x=%f_er=%.0e\n", ________x,y,f,e); ______} ______dydx_=_y; ______y_=_y_+_dydx*h; ____} __} __printf("\n"); __//_y_=_1/e^4x __b_=_4; __for(n=100;n<=10000;n*=100){ ____h_=_(b-a)/n; ____printf("y'_=_-4y:_h(=dx)_=_%.1e_(y=1/e^4x)\n",h); ____x_=_a;_y_=_1; ____for(k=0;k<=n;k++)_{ ______x_=_k*h; ______if(k%(n/m)==0)_{ ________f_=_exp(-4*x); ________e_=_fabs(y-f); ________printf("x=%.2f,_y=%f,_1/e^4x=%f_er=%.0e\n", ________x,y,f,e); ______} ______dydx_=_-4*y; ______y_=_y_+_dydx*h; ____} __} __return_0; } 分かる方がいましたら、回答よろしくお願いします。

専門家に質問してみよう