如何编写代码来计算C++中多个变量函数的偏导数?
How to write code to calculate partial derivative of several variable function in C++?
我已经编写了代码来计算单变量函数在某个点的导数,方法是制作一个名为“Der”的 class。在class Der
中,我定义了两个私有变量double f
和double df
以及一个print()
函数来打印f
和df
的值。在 class 中,我重载了运算符 +, -, *, /, ^
来计算函数的和、差、乘等的导数。我无法展示整个代码,因为它很长,但我会展示一些片段来提供一个想法。
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
w.r.tx, y, z
在(2, 4, 5)
点的偏导数。但是,我只需要一些关于如何编写偏导数计算器代码的想法。
您似乎非常接近解决方案,但在跨多个维度定义函数的步骤上遇到困难。
您需要多个成员变量,而不是一个成员变量 df
,每个偏导数一个。你可以 hard-code 他们:
double dfx, dfy, dfz;
或使用容器:
double df[3];
我暂时使用 hard-coding。 (容器是一个非常重要的话题,std::vector
在几乎所有方面都比数组好,但一次只有一件事。)
将另一个变量从 x
重命名为 v
也是明智的,因为它表示函数在点处的 值 兴趣,而不是点的位置。 (这个值得思考。)
老构造函数取一值一导:
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, 0), y(4, 0, 1, 0), z(5, 0, 0, 1);
并且算术运算的逻辑很简单。例如,两个函数乘积的第一部分:
dfx = A.v * B.dfx + A.dfx * B.v;
(事实上,您可以从当前的 class 中抽象出算术,并将其用于旧的和新的 classes,但一次只能做一件事。)
我已经编写了代码来计算单变量函数在某个点的导数,方法是制作一个名为“Der”的 class。在class Der
中,我定义了两个私有变量double f
和double df
以及一个print()
函数来打印f
和df
的值。在 class 中,我重载了运算符 +, -, *, /, ^
来计算函数的和、差、乘等的导数。我无法展示整个代码,因为它很长,但我会展示一些片段来提供一个想法。
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
w.r.tx, y, z
在(2, 4, 5)
点的偏导数。但是,我只需要一些关于如何编写偏导数计算器代码的想法。
您似乎非常接近解决方案,但在跨多个维度定义函数的步骤上遇到困难。
您需要多个成员变量,而不是一个成员变量 df
,每个偏导数一个。你可以 hard-code 他们:
double dfx, dfy, dfz;
或使用容器:
double df[3];
我暂时使用 hard-coding。 (容器是一个非常重要的话题,std::vector
在几乎所有方面都比数组好,但一次只有一件事。)
将另一个变量从 x
重命名为 v
也是明智的,因为它表示函数在点处的 值 兴趣,而不是点的位置。 (这个值得思考。)
老构造函数取一值一导:
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, 0), y(4, 0, 1, 0), z(5, 0, 0, 1);
并且算术运算的逻辑很简单。例如,两个函数乘积的第一部分:
dfx = A.v * B.dfx + A.dfx * B.v;
(事实上,您可以从当前的 class 中抽象出算术,并将其用于旧的和新的 classes,但一次只能做一件事。)