2017-05-29 8 views
-2

こんにちは私は、異なる正弦関数の解を見つけるためのプログラムを作っています。 私は一定の間隔で各関数の解をテストできるように、sin(2x)、sin(4x)、sin(6x)、.... sin(12x)を配列に格納したいと思っていました。多項式をサイン関数に入れる方法は? (re)

ここでのコード...

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

int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double)); 


int main() 
{ 
    double x, x0 = 2.0, xf = 4.0, tolerance = FLT_EPSILON; 
    int status, i, j; 
    double (*pf[6])(double); 

    for (i = 1; i < 7; i++) 
    { 
     pf[i] = sin(2 * i * x); 
     // error : cannot assign double value to double(*) (double) entity 
     // How to make functions like sin(2x), sin(4x), .. etc?? 
     status = bisect(&x, x0, xf, tolerance, pf[i]); 

と私は機能与えられたものをポイントで見つけることが二分()関数を作成した0

二分関数は、main関数の下で返します。 x0は始点、xfは終点、iは誤差をチェックするための公差を設定します。二等分関数はforループの中間値定理を使用します。

forループでbisect関数を呼び出し、* pf [i]を使ってサイン関数を渡して解を探したいと思います。

 if (status == -1) 
      printf("Error : bisect() failed, invalid tolerance\n"); 
     else if(status == -2) 
      printf("Error : bisect() failed, invalid end points\n"); 
     else 
      printf("x = %f, sin(x) = %g\n", x, pf[i](x)); 


    } 
    return 0; 
} 

int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double)) 
{ 
    double xleft = x0, fleft; 
    double xright = xf; 
    double xmid, fmid; 

    if (tolerance <= 0.0) 
     return -1; 

    fleft = func(x0); 

    if (fleft * func(xf) > 0.0) 
     return -2; 

    xmid = (xleft+xright) /2.0; 
    fmid = func(xmid); 

    while (fabs(fmid) > tolerance) 
    { 
     if (fleft * fmid <= 0) 
     { 
      xright = xmid; 
     } 

     else 
     { 
      xleft = xmid; 
      fleft = fmid; 
     } 
     xmid = (xleft + xright)/2.0; 
     fmid = func(xmid); 

    } 
    *x = xmid; 
    return 0; 
} 

それはなど、何の罪について(2倍)、罪(4倍)しかしなど、罪、COSのための解決策を見つけるのは簡単だ??どうすればこれらの関数を* pf []に保存できますか? (関数ポインタの配列)

任意の提案が役立ちます。

+1

あなたは既にこの質問を数時間前に投稿しました。再投稿はここではうまくいきません。オリジナルを編集して再オープンを要求する必要があります(クローズした場合)。これは本当に良くないことに注意してください。あなたはコメントの中に情報を持っています、あなたは考えなかったようです。 [ask]を読んでください。私たちは家庭教師/コーディングサイトではありません。 – Olaf

+0

@Olaf私の謝罪。私は次回よりうまくやるよ。ご指摘ありがとうございます。 –

答えて

3

Cでは、元のsin関数をラップする複数の関数を作成せずに、必要な処理を行うことはできません。おそらく、

悲しいこと

double sin2(double value) 
{ 
    return sin(2 * value); 
} 

double sin4(double value) 
{ 
    return sin(4 * value); 
} 

// Etc... 

int main(void) 
{ 
    double (*pf[6])(double) = { 
     sin2, sin4, ... 
    }; 

    for (int i = 0; i < 6; ++i) 
    { 
     printf("%f\n", pf[i](0.5)); 
    } 
} 
+0

あなたの助けを感謝します!どうしてそんなに簡単にできましたか? :) –

0

のようなもの、Cは、あなたが望むように見える何である、本格的なクロージャをサポートしていません。

しかし、doubleを返してdoubleを返し、それをbisect関数に渡すように、プログラム内のカスタム関数を定義することができます。例えば

:あなたのケースでは

double some_function(double x) { 
    // You can do anything you like, as long as you return a double. 
    return sin(2 * x); 
} 

、別にiのすべての値に対してカスタム関数を指定する必要が少し面倒かもしれませんが、あなたは、おそらく使用して、いくつかの繰り返しを取り除くことができ

#define DEFINE_SIN_POLY(i) double sin_poly_##i##(double x) { \ 
    return sin(2 * i * x); \ 
} 

DEFINE_SIN_POLY(2); 
DEFINE_SIN_POLY(3); // etc. 

// then, you can simply access these functions as 
sin_poly_2, sin_poly_3, etc. 

これは少し醜いです。 C++を使用する場合は、関数の型やラムダなどのより高度な機能を利用して、コードをより簡潔にすることができます。パフォーマンスはほとんど損なわれません。

+1

本当に便利です。長いコードから私のコードを保つためにありがとう。 –

+0

あなたは大歓迎です!少しでも私が助けることができてうれしい。繰り返しますが、前にも述べたように、C++やPythonなどのアルゴリズムを素早くプロトタイプ化して遊んでいれば、より生産的になるかもしれません。 –

0

その場で関数を作成する必要があります。これには、パラメータの種類のメモリがあります。これらのパラメータをグローバルにするか、closureと呼ばれるものを作成してください。

C自体にはこのようなことはサポートされていませんが、必要な動作を持つヒープ上に新しい関数を作成することで、エミュレートできます。これを行うのに役立つ図書館があります。

libffiは、Cでクロージャを作成できるようなライブラリですが、高度な技術です。

ドキュメントは、いくつかの例を提供する:エラーのhttp://www.chiark.greenend.org.uk/doc/libffi-dev/html/Closure-Example.html

0

理由は

pf[i] = sin(2 * i * x); 

2*i*xの現在の値に等しい引数でsin()関数を呼び出すことです。結果はその特定の値の正弦であり、関数ではありません。

基本的に、標準Cはクロージャをサポートしていません。

ではなく、直接または間接的にループ内の関数のセットを作成しようとするよりも、必要な効果を得るための最も簡単な方法は、余分な引数を追加し

int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double)) 

からbisect()の仕様を変更することであろう

int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double), double factor) 

と、func(something)が呼び出されるすべての場所で、func(something*factor)に変更。たとえば、fmid = func(xmid)fmid = func(xmid * factor)に変更します。

は、発信者(main())で、これは、アレイ全体pfの必要性を排除すること

for (i = 1; i < 7; i++) 
{ 
    pf[i] = sin(2 * i * x); 
    // error : cannot assign double value to double(*) (double) entity 
    // How to make functions like sin(2x), sin(4x), .. etc?? 
    status = bisect(&x, x0, xf, tolerance, pf[i]); 

for (i = 1; i < 7; i++) 
{ 
    // How to make functions like sin(2x), sin(4x), .. etc 
    status = bisect(&x, x0, xf, tolerance, sin, 2*i); 
に注意のループを変更します。これは、 2*iの値を factorのような関数に渡すことによって動作し、それを使用することができます。

もっと一般的には、Cの教科書を読む時間が必要です。 PythonはC言語ではできませんが、C言語では簡単には模倣できないようないくつかの機能(この場合はクロージャーのような)をサポートしているので、さまざまな問題が発生します。多くの場合、プログラムを構成する方法が非常に異なっています。

+0

これは本当にうまくやる方法です。ご協力いただきありがとうございます。そして、私はyoutubeの代わりにCの本を読んでいきます。 –

関連する問題