C++ 微积分 - 求导 - 解析法(符号计算)
C++ 微积分 - 求导 - 解析法(符号计算)
C++ 微积分 - 求导 - 解析法(符号计算)
flyfish
解析法(符号计算)需要为每一个可能的函数及其组合编写解析表达式,以推导出其导数。这通常涉及到实现微积分中的各种求导规则和公式。解析法的目的是通过符号操作直接推导出导数表达式,因此需要涵盖广泛的函数类型和运算。
以下是一些常见的函数及其解析求导的规则:
1. 多项式函数
对于多项式函数
f
(
x
)
=
a
x
n
f(x) = ax^n
f(x)=axn,其导数为:
f
′
(
x
)
=
n
a
x
n
−
1
f'(x) = nax^{n-1}
f′(x)=naxn−1
2. 指数函数
对于指数函数
f
(
x
)
=
e
x
f(x) = e^x
f(x)=ex,其导数为:
f
′
(
x
)
=
e
x
f'(x) = e^x
f′(x)=ex对于一般形式
f
(
x
)
=
a
x
f(x) = a^x
f(x)=ax,其导数为:
f
′
(
x
)
=
a
x
ln
(
a
)
f'(x) = a^x \ln(a)
f′(x)=axln(a)
3. 对数函数
对于对数函数
f
(
x
)
=
ln
(
x
)
f(x) = \ln(x)
f(x)=ln(x),其导数为:
f
′
(
x
)
=
1
x
f'(x) = \frac{1}{x}
f′(x)=x1
4. 三角函数
正弦函数:
f
(
x
)
=
sin
(
x
)
f(x) = \sin(x)
f(x)=sin(x),导数为
f
′
(
x
)
=
cos
(
x
)
f'(x) = \cos(x)
f′(x)=cos(x)
余弦函数:
f
(
x
)
=
cos
(
x
)
f(x) = \cos(x)
f(x)=cos(x),导数为
f
′
(
x
)
=
−
sin
(
x
)
f'(x) = -\sin(x)
f′(x)=−sin(x)
正切函数:
f
(
x
)
=
tan
(
x
)
f(x) = \tan(x)
f(x)=tan(x),导数为
f
′
(
x
)
=
sec
2
(
x
)
f'(x) = \sec^2(x)
f′(x)=sec2(x)
5. 反三角函数
反正弦函数:
f
(
x
)
=
arcsin
(
x
)
f(x) = \arcsin(x)
f(x)=arcsin(x),导数为
f
′
(
x
)
=
1
1
−
x
2
f'(x) = \frac{1}{\sqrt{1-x^2}}
f′(x)=1−x21
反余弦函数:
f
(
x
)
=
arccos
(
x
)
f(x) = \arccos(x)
f(x)=arccos(x),导数为
f
′
(
x
)
=
−
1
1
−
x
2
f'(x) = \frac{-1}{\sqrt{1-x^2}}
f′(x)=1−x2−1
反正切函数:
f
(
x
)
=
arctan
(
x
)
f(x) = \arctan(x)
f(x)=arctan(x),导数为
f
′
(
x
)
=
1
1
+
x
2
f'(x) = \frac{1}{1+x^2}
f′(x)=1+x21
6. 复合函数(链式法则)
对于复合函数
f
(
g
(
x
)
)
f(g(x))
f(g(x)),其导数为:
(
f
(
g
(
x
)
)
)
′
=
f
′
(
g
(
x
)
)
⋅
g
′
(
x
)
(f(g(x)))' = f'(g(x)) \cdot g'(x)
(f(g(x)))′=f′(g(x))⋅g′(x)
C++ 实现解析求导
在 C++ 中,实现解析法需要为每一个函数类型及其组合编写相应的求导函数。
简单的解析求导示例: 下面是一个简单的符号计算示例,计算
f
(
x
)
=
x
3
+
2
x
f(x) = x^3 + 2x
f(x)=x3+2x 的导数:
-
表达式基类
Expression
str()
: 返回表达式的字符串表示形式。
derivative()
: 计算并返回表达式的导数。 -
常数类
Constant
str()
: 返回常数的字符串表示形式。
derivative()
: 返回常数的导数,常数的导数始终为 0。
getValue()
: 提供获取常数值的功能。 -
变量类
Variable
str()
: 返回变量x
的字符串表示形式。
derivative()
: 返回变量x
的导数,变量的导数始终为 1。 -
加法类
Add
str()
: 返回加法表达式的字符串表示形式,其中左右操作数用括号括起来以确保运算顺序。
derivative()
: 计算加法表达式的导数,即左右操作数导数的和。 -
乘法类
Multiply
str()
: 返回乘法表达式的字符串表示形式。如果左右操作数是Add
或Multiply
类型,则加上括号以确保正确的运算顺序。
derivative()
: 计算乘法表达式的导数,基于乘积法则(u * v)' = u' * v + u * v'
。 -
主函数
main
构造函数f(x) = x^3 + 2x
:
x^3
使用三个Variable
类实例相乘得到。
2x
使用一个Constant
类和一个Variable
类实例相乘得到。
计算f(x)
的导数f'(x)
。
输出函数f(x)
和其导数f'(x)
的字符串表示。
#include <iostream>
#include <string>
#include <memory>
// 表示一个符号表达式的基类
class Expression {
public:
virtual std::string str() const = 0; // 表示表达式的字符串形式
virtual std::unique_ptr<Expression> derivative() const = 0; // 计算表达式的导数
virtual std::unique_ptr<Expression> clone() const = 0; // 克隆当前表达式
virtual ~Expression() {}
};
// 表示常数的类
class Constant : public Expression {
double value;
public:
Constant(double val) : value(val) {}
std::string str() const override {
return std::to_string(value);
}
std::unique_ptr<Expression> derivative() const override {
return std::make_unique<Constant>(0); // 常数的导数为 0
}
std::unique_ptr<Expression> clone() const override {
return std::make_unique<Constant>(value); // 克隆常数
}
double getValue() const { return value; } // 获取常数值
};
// 表示变量 x 的类
class Variable : public Expression {
public:
std::string str() const override {
return "x";
}
std::unique_ptr<Expression> derivative() const override {
return std::make_unique<Constant>(1); // x 的导数为 1
}
std::unique_ptr<Expression> clone() const override {
return std::make_unique<Variable>(); // 克隆变量
}
};
// 表示加法运算的类
class Add : public Expression {
std::unique_ptr<Expression> left, right;
public:
Add(std::unique_ptr<Expression> l, std::unique_ptr<Expression> r)
: left(std::move(l)), right(std::move(r)) {}
std::string str() const override {
std::string leftStr = left->str();
std::string rightStr = right->str();
return "(" + leftStr + " + " + rightStr + ")";
}
std::unique_ptr<Expression> derivative() const override {
// 加法导数是各自导数的和
return std::make_unique<Add>(left->derivative(), right->derivative());
}
std::unique_ptr<Expression> clone() const override {
return std::make_unique<Add>(left->clone(), right->clone()); // 克隆加法表达式
}
};
// 表示乘法运算的类
class Multiply : public Expression {
std::unique_ptr<Expression> left, right;
public:
Multiply(std::unique_ptr<Expression> l, std::unique_ptr<Expression> r)
: left(std::move(l)), right(std::move(r)) {}
std::string str() const override {
// 处理乘法表达式中的优先级和括号
std::string leftStr = left->str();
std::string rightStr = right->str();
// 在乘法的左右操作数前加括号(如果必要)
if (dynamic_cast<Add*>(left.get()) || dynamic_cast<Multiply*>(left.get())) {
leftStr = "(" + leftStr + ")";
}
if (dynamic_cast<Add*>(right.get()) || dynamic_cast<Multiply*>(right.get())) {
rightStr = "(" + rightStr + ")";
}
return leftStr + " * " + rightStr;
}
std::unique_ptr<Expression> derivative() const override {
// 乘法导数根据乘积法则计算
// (u * v)' = u' * v + u * v'
return std::make_unique<Add>(
std::make_unique<Multiply>(left->derivative()->clone(), right->clone()),
std::make_unique<Multiply>(left->clone(), right->derivative()->clone())
);
}
std::unique_ptr<Expression> clone() const override {
return std::make_unique<Multiply>(left->clone(), right->clone()); // 克隆乘法表达式
}
};
int main() {
// 构造函数 f(x) = x^3 + 2x
auto x = std::make_unique<Variable>();
auto x_cubed = std::make_unique<Multiply>(
std::make_unique<Variable>(),
std::make_unique<Multiply>(std::make_unique<Variable>(), std::make_unique<Variable>())
); // x^3
auto two_x = std::make_unique<Multiply>(std::make_unique<Constant>(2), std::make_unique<Variable>()); // 2x
auto f = std::make_unique<Add>(std::move(x_cubed), std::move(two_x));
// 计算 f'(x)
auto df = f->derivative();
// 输出函数和导数的表达式
std::cout << "f(x) = " << f->str() << std::endl;
std::cout << "f'(x) = " << df->str() << std::endl;
return 0;
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)