ニュートン法 関数ポインタ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
kanaya
記事: 5
登録日時: 4年前

ニュートン法 関数ポインタ

#1

投稿記事 by kanaya » 4年前

以下のようなソースコードがあります。(x0は初期値、eは許容条件)

コード:

#include <stdio.h>
#include <math.h>

void bisection(double (*func)(double), double xJ, double xK, double e);
void newton(double (*func)(double), double (*dfunc)(double),double x0, double e);
double func1(double x);
double dfunc1(double x);
double func2(double x);
double dfunc2(double x);
int main(int argc, char* argv[])
{
	newton(func1,dfunc1,0.5,0.0001);
	newton(func2,dfunc2,0.5,0.0001);
	return 0;
}
void bisection(double (*func)(double), double xJ, double xK, double e)
{
	int i;
	double x;
	double tmp;

	x=(xJ+xK)/2;

	printf("#i\tx\tf(x)\n");
	for(i=0;i<100;i++)
	{
		tmp=(*func)(x);
		printf("%d\t%f\t%f\n",i,x,tmp);
		if( fabs(tmp) < e)break;
		if( tmp*(*func)(xJ) < 0 )xK=x;
		else xJ=x;
		x=(xJ+xK)/2;
	}
	printf("#x=%f\n",x);
}
void newton(double (*func)(double), double (*dfunc)(double),double x0, double e)
{
	int i;
	double x;
	double tmp;

	x=x0;

	printf("#i\tx\tf(x)\n");
	for(i=0;i<100;i++)
	{
		tmp=func1(x);
		printf("%d\t%f\t%f\n",i,x,tmp);
		if( fabs(tmp) < e)break;
		x=x-func1(x)/dfunc1(x);
	}
	printf("#x=%f\n",x);
}
double func1(double x)
{
	return x-0.1;
}
double dfunc1(double x)
{
	return 1;
}
double func2(double x)
{
	return pow(x,4)-4*pow(x,3)+1;
}
double dfunc2(double x)
{
	return 4*pow(x,3)-4*3*pow(x,2);
}
func1ではx-0.1=0となるようなxの近似値を求め、func2ではx^4-4x^3+1=0となるようなxの近似値を求めます。ここでニュートン法の関数に関数ポインタによって引数を与えたいです。
(func:f(x)=0を計算したいf(x)の関数ポインタ、dfunc:f(x)=0を計算したい導関数f)
主にソースコード中の47行目tmp=func1(x);と50行目x=x-func1(x)/dfunc1(x);の部分を変更すればよいと考えますが、どう変更すれば引数を与えられるのか見当が付きません。教えていただきたいです。

YuO
記事: 941
登録日時: 9年前
住所: 東京都世田谷区

Re: ニュートン法 関数ポインタ

#2

投稿記事 by YuO » 4年前

引数としてfuncおよびdfuncとして渡されているのだから,それをそのまま使えばよいのではないでしょうか。

アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: ニュートン法 関数ポインタ

#3

投稿記事 by みけCAT » 4年前

bisection関数ではできているので、同じようにするだけでしょう。

コード:

void newton(double (*func)(double), double (*dfunc)(double),double x0, double e)
{
	int i;
	double x;
	double tmp;

	x=x0;

	printf("#i\tx\tf(x)\n");
	for(i=0;i<100;i++)
	{
		tmp=(*func)(x);
		printf("%d\t%f\t%f\n",i,x,tmp);
		if( fabs(tmp) < e)break;
		x=x-(*func)(x)/(*dfunc)(x);
	}
	printf("#x=%f\n",x);
}
もしくは、関数ポインタが指す関数は明示的にデリファレンスしなくても呼び出せます。

コード:

void newton(double (*func)(double), double (*dfunc)(double),double x0, double e)
{
	int i;
	double x;
	double tmp;

	x=x0;

	printf("#i\tx\tf(x)\n");
	for(i=0;i<100;i++)
	{
		tmp=func(x);
		printf("%d\t%f\t%f\n",i,x,tmp);
		if( fabs(tmp) < e)break;
		x=x-func(x)/dfunc(x);
	}
	printf("#x=%f\n",x);
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る