问题描述
我已经编写了代码,通过制作一个称为“ Der”的类来计算单个变量函数的导数。在class Der
中,我定义了两个私有变量double f
和double df
以及一个print()
函数来打印f
和df
的值。在类内部,我使运算符+,-,*,/,^
重载,以计算函数之和,差,乘法等的导数。我不能显示整个代码,因为它很长,但是我将显示一些代码片段来说明一个想法。
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;
(实际上,您可以从当前类中抽象出该算法,并将其用于新旧类,但一次只能做一件事。)