如何编写代码以计算C ++中几个变量函数的偏导数?

问题描述

我已经编写了代码,通过制作一个称为“ Der”的类来计算单个变量函数的导数。在class Der中,我定义了两个私有变量double fdouble df以及一个print()函数来打印fdf的值。在类内部,我使运算符+,-,*,/,^ 重载,以计算函数之和,差,乘法等的导数。我不能显示整个代码,因为它很长,但是我将显示一些代码片段来说明一个想法。

class Der{
private:
    double f;  // function value at x
    double df; // derivative of function at x
public:
    Der();
    Der(double);
    Der operator+(Der); // f + g
    Der operator-(Der); // f - g
    Der operator*(Der); // f * g
    Der operator/(Der); // f / g
       
    friend Der operator+(double,Der); //c+f
    friend Der operator-(double,Der); //c-f
    friend Der operator*(double,Der); //c*f
    friend Der operator/(double,Der); //c/f
    Der operator^(double); // f^c,Where c is constant
   
    friend Der sin(Der);
    friend Der cos(Der);
    friend Der tan(Der);
    friend Der log(Der);
    friend Der exp(Der);
    
    void print();
};

Der :: Der(){}

Der :: Der(double x){
    this->f = x;
    this->df = 1;
}

Der Der :: operator+(Der g){
    Der h;
    h.f = this->f + g.f;
    h.df = this->df + g.df;
    return h;
}

Der sin(Der g){
    Der h;
    h.f = sin(g.f);
    h.df = cos(g.f)*g.df;
    return h;
}
void Der :: print(){
    cout<<"Derivative of function at a point : "<<df<<endl;
}

int main()
    {
        Der x(10),f;
        f = x^2+x^3;
        f.print();
    }

现在,我想使用此导数计算器来计算多个变量函数的偏导数,并最终计算出该函数的梯度。我有一些模糊的想法,但是我无法在代码中实现它。我是C ++编程的初学者,所以如果您不使用太多高级概念,将会很有帮助。

任何帮助将不胜感激。谢谢!

编辑:我添加Der的使用方式。该程序应接受诸如x(2),y(4),z(5)之类的自变量和诸如f(x,y,z)=x^2*y*z+log(x*y*z)之类的函数的输入。然后,它将在点f处以数组形式给出x,z w.r.t (2,4,5)的偏导数。但是,我只需要了解如何对偏导数计算器进行编码即可。

解决方法

您似乎非常接近解决方案,但是在跨多个维度定义函数的步骤中苦苦挣扎。

您需要多个变量,而不是一个成员变量df,每个偏导数一个。您可以对它们进行硬编码:

double dfx,dfy,dfz;

或使用容器:

double df[3];

我现在将使用硬编码。 (容器是一个至关重要的话题,std::vector在几乎所有方面都比数组要好,但一次只能做一件事。)

明智的做法是将另一个变量从x重命名为v,因为它表示感兴趣点而不是位置的函数的 value 的重点。 (这值得考虑。)

旧的构造函数取一个值和一个导数:

Der :: Der(double x){
    this->f = x;
    this->df = 1;
}

这可以更好地使用初始化程序来编写:

Der :: Der(double nx): x(nx),df(1)
{}

这很容易重写构造函数以采用三个偏导数:

Der :: Der(double nv,double dx,double dy,double dz): v(nv),dfx(dx),dfy(dy),dfz(dz)
{}

现在我们可以声明函数了:

Der x(2,1,0),y(4,z(5,1);

算术运算的逻辑很简单。例如,两个函数乘积的第一部分:

dfx = A.v * B.dfx + A.dfx * B.v;

(实际上,您可以从当前类中抽象出该算法,并将其用于新旧类,但一次只能做一件事。)