如何将多项式置于正弦函数中? (回覆)

时间:2017-05-29 11:54:17

标签: c

您好我正在制作一些程序来寻找不同正弦函数的解决方案。 我想犯罪(2x),sin(4x),sin(6x),...... sin(12x)并将它们存储到数组中,以便我可以在给定的时间间隔内测试每个函数的解。

下面'代码......

#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]);

我创建了bisect()函数来查找给定函数返回0的点。

二分功能低于主要功能。 x0是起点,xf是终点,我设置了检查错误的容差。平分函数在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;
}

很容易找到罪,cos等的解决方案但是罪(2x),罪(4x)等等?我怎样才能将这些功能存储在* pf []中? (函数指针数组)

任何建议都会有所帮助。

4 个答案:

答案 0 :(得分: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));
    }
}

答案 1 :(得分: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 ++,您可以利用更高级的功能,例如函数类型,lambdas等,使您的代码更简洁,几乎不会损失性能。

答案 2 :(得分:0)

您需要动态创建函数,这些函数具有某些参数的内存。您可以将这些参数设为全局,也可以创建所谓的closure

即使C本身不支持这样的事情,你也可以通过在堆上创建具有所需行为的新函数来模拟它。有些库可以帮助您实现这一目标。

libffi是一个允许你在C中创建闭包的库,尽管它是一种非常先进的技术。

文档提供了一些示例:http://www.chiark.greenend.org.uk/doc/libffi-dev/html/Closure-Example.html

答案 3 :(得分:0)

错误的原因是

{"even": true}

调用pf[i] = sin(2 * i * x); 函数,其参数等于sin()的当前值。结果是该特定值的正弦值,而不是函数。

基本上,标准C不支持闭包。

获得所需效果的最简单方法是改变2*i*x的规范,而不是试图在循环中直接或间接创建一组函数,而不是

bisect()

添加额外参数

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

并且,在调用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()

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); 。它的工作原理是将pf的值传递给函数2*i,然后可以使用它。

但是,更一般地说,您需要花时间阅读C教科书。试图通过类比Python来学习C会导致各种各样的问题,因为Python支持很多功能(比如这种情况下的闭包),而C则没有,并且在C中不能轻易模仿它们。它们是非常不同的语言和通常需要非常不同的方法来构建程序。