当前位置: 首页 > news >正文

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)=naxn1

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)=1x2 1
反余弦函数: 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)=1x2 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 的导数:

  1. 表达式基类 Expression
    str(): 返回表达式的字符串表示形式。
    derivative(): 计算并返回表达式的导数。

  2. 常数类 Constant
    str(): 返回常数的字符串表示形式。
    derivative(): 返回常数的导数,常数的导数始终为 0。
    getValue(): 提供获取常数值的功能。

  3. 变量类 Variable
    str(): 返回变量 x 的字符串表示形式。
    derivative(): 返回变量 x 的导数,变量的导数始终为 1。

  4. 加法类 Add
    str(): 返回加法表达式的字符串表示形式,其中左右操作数用括号括起来以确保运算顺序。
    derivative(): 计算加法表达式的导数,即左右操作数导数的和。

  5. 乘法类 Multiply
    str(): 返回乘法表达式的字符串表示形式。如果左右操作数是 AddMultiply 类型,则加上括号以确保正确的运算顺序。
    derivative(): 计算乘法表达式的导数,基于乘积法则 (u * v)' = u' * v + u * v'

  6. 主函数 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 + 2xauto 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^3auto two_x = std::make_unique<Multiply>(std::make_unique<Constant>(2), std::make_unique<Variable>()); // 2xauto 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;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Laravel为什么会成为最优雅的PHP框架?
  • B - 02-计算球的体积 51Nod - 3266
  • Python可视化开发全面教程
  • 使用 1panel面板 部署 php网站
  • 电路元件基本知识详解
  • 基础实验回顾
  • 【密码学】椭圆曲线密码体制(ECC)
  • 基于深度学习的联邦学习
  • 【Python】任推邦近30日推广数据采集+推送
  • Open3D 计算点云的归一化协方差矩阵
  • JAVA中的重载
  • opencv-图像仿射变换
  • 北京汽车美容元宇宙:数字化浪潮下的车美服务新革命
  • JavaScript 对话框式弹出提示框 PopoverTip 实现详解
  • JavaFX布局-ToolBar
  • [case10]使用RSQL实现端到端的动态查询
  • [译] 怎样写一个基础的编译器
  • Angular Elements 及其运作原理
  • Facebook AccountKit 接入的坑点
  • JavaScript设计模式与开发实践系列之策略模式
  • javascript数组去重/查找/插入/删除
  • js 实现textarea输入字数提示
  • Laravel5.4 Queues队列学习
  • node入门
  • Redis在Web项目中的应用与实践
  • Sequelize 中文文档 v4 - Getting started - 入门
  • SOFAMosn配置模型
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 分享几个不错的工具
  • 讲清楚之javascript作用域
  • 前端面试之CSS3新特性
  • 微信支付JSAPI,实测!终极方案
  • 想使用 MongoDB ,你应该了解这8个方面!
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • Android开发者必备:推荐一款助力开发的开源APP
  • Spring第一个helloWorld
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #stm32整理(一)flash读写
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • ()、[]、{}、(())、[[]]命令替换
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (day 12)JavaScript学习笔记(数组3)
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (论文阅读40-45)图像描述1
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)