024_Symbolic_Math_in_Matlab符号数学工具箱的使用思路

news2024/11/28 10:59:38

在这里插入图片描述

符号运算与数值计算

缘,妙不可言

给本科、硕士、博士、研究实习员、助理研究员、副研究员改过Matlab代码,最有意思也最好玩的就是兄弟姐妹们喜欢把符号运算跟数值计算混合在一起。

从概念上看,还是挺不错的。

大佬们的计划都是这样的,先syms一手,把公式输进去,在符号领域推导一番,最后代入数值,得到结果。

【扶额科】……

【大佬斜眼科,云】那你就说Matlab有没有这个功能。

【颔首科】……

【大佬偏头科,云】那你就说报没报错。

【摇头科】……
【挣扎科】那你看结果对不对。

【大佬仰天科,云】结果不对那是你的问题口牙!

其实这个工作流程的确是存在而且好用的,Matlab本来也就是这样设计的。

下面就稍微介绍一下,如何顺滑地把符号计算和数值计算结合起来。

建议的实践

结论先行:把符号计算和数值计算分开

工作的流程可以是:

公式符号推导
需要的函数文件
数值计算与分析
展现与报告结果

我的建议是,把符号推导的部分专门放在一个LiveScript文件里,推导的结果,产生一系列函数文件,这些函数文件就是不同的Matlab函数,后面就进行正常的Matlab数值计算工程应用。

理由

理由主要是:符号运算中的符号会污染所有的计算,把一切涉及到符号的表达式变成符号变量和表达式,这会使Matlab高效矩阵数值计算的优势无法发挥。

符号计算真的很慢、很慢很慢。

我们举一个简单的例子:

syms f(x,y,z)
f(x,y,z) = y*z*sin(x) + x*sin(z)*cos(y) - z^3;

[xDouble,yDouble,zDouble] = meshgrid(1:20,1:50,1:20);

接下来我们比较一下符号计算和数值计算的时间:

>> timeit(@()f(xDouble,yDouble,zDouble), 1)

ans =

    2.0569

上面的式子中,我们调用timeit函数是还包括了输出的赋值(1个输出变量),相当于我们在通过多次计算平均来评估fDouble = f(xDouble,yDouble,zDouble)的时间。

那么我们在来看一下同样电脑上数值计算的时间。

>> f1 = matlabFunction(f)

f1 =

  包含以下值的 function_handle:

    @(x,y,z)-z.^3+y.*z.*sin(x)+x.*cos(y).*sin(z)

>> timeit(@()f1(xDouble,yDouble,zDouble), 1)

ans =

   9.3786e-04

先不管这个matlabFunction函数,我们可以看到,这个时间差距是大于3个数量级的。

还有一个,如果你们说问题出在这里的点运算符上,那么我们可以看一下这个:

>> syms f3(x,y,z)
>> f3(x,y,z) = y.*z.*sin(x) + x.*sin(z).*cos(y) - z.^3;
>> timeit(@()f3(xDouble,yDouble,zDouble), 1)

ans =

    2.1108

综上所述,不要把任何符号带入成规模的数值计算中,比如大范围的网格计算,循环数据处理等。

接下来,就主要介绍一下如何把符号推导的结果转化为数值计算中可以高效使用的函数。

符号计算工具箱

在前面考虑时间的例子中,我们使用了matlabFunction函数,在2008b之后的版本中,这个函数就是符号计算工具箱的一部分。

在符号计算数学工具箱中,主要处理的对象是:

  • 符号常量:准确表达的数值
  • 符号变量:数学上的代数变量
  • 符号表达式:符号表达式

符号常量和符号变量

通过sym函数,我们可以定义符号常亮和符号变量。

a = sym(1/3);
piSym = sym(pi);

这有什么区别呢?

>> sin(piSym)

ans =

0

>> sin(pi)

ans =

   1.2246e-16

可以通过函数vpa将浮点数转化为符号常量。

这个函数默认截取32位有效数字,可以通过第二个参数指定有效数字位数。

>> vpa(pi, 100)

ans =
 
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

新建符号变量,同样用sym函数,它有两种调用方式,除了能建立单纯的数学变量,还能建立符号变量向量和矩阵。

>> sym('x', [3, 3])
 
ans =
 
[x1_1, x1_2, x1_3]
[x2_1, x2_2, x2_3]
[x3_1, x3_2, x3_3]

另外一种方式就是个语法躺,把符号变量直接列在一起。

>> syms x y z [3 3]

这样三个符号变量矩阵,这个矩阵的元素都是符号变量。约定向量的元素是x1,x2,x3,...,矩阵的元素是x1_1,x1_2,x1_3,...

符号表达式

符号表达式是符号变量的组合,可以通过涉及到符号变量和符号常量的运算得到。

syms x y z
f = x^2 + y^2 + z^2;

这样定义出来的f就是一个sym类型的对象,可以进行各种运算。

或者,可以用symfun函数,定义一个函数。

syms x y z
g = symfun(x^2 + y^2 + z^2, [x, y, z]);

或者,还可以这样定义,与上面完全相同,通常,下面这个方式更加简洁。

syms h(x,y,z)
h(x,y,z) = x^2 + y^2 + z^2;

symsymfun 的区别

sym定义的是一个符号表达式(所有的符号都是符号表达式),symfun定义的是一个符号函数。

我找了好久,也没有找到太大的本质区别,在实际的使用中,symfun可以当做函数调用,把对应的形式符号替换为实参所对应的符号表达式,最终的结果是一个符号表达式(sym)。

当我们推导得到的符号表达式或者符号函数之后,我们可以通过matlabFunction函数,将其转化为函数句柄,这样就可以在数值计算中使用。在这一步,无论是sym还是symfun,都是可以的。

从继承关系上来讲,symfunsym的子类,所以symfun是一个sym

sym
#s
#mathmlOutput
#Digits
+loadobj(x)
+zeros(varargin)
+ones(varargin)
+empty(varargin)
+inf(varargin)
+nan(varargin)
+eye(varargin)
+cast(a)
+sym(x, n, a) : sym
+delete(x)
+argnames(x) : sym
+formula(x) : sym
+length(x) : int
+uminus(x) : sym
+uplus(x) : sym
+times(A, B) : sym
+mpower(A, p) : sym
+power(A, p) : sym
+rdivide(A, B) : sym
+ldivide(A, B) : sym
+mrdivide(A, B) : sym
+mldivide(A, B) : sym
+eq(A, B) : bool
+ne(A, B) : bool
+logical(A) : bool
+all(A, dim) : bool
+find(A, varargin) : varargout
symfun
- vars
+symfun(x, inputs) : symfun

符号表达式的转化

基础调用方式:转化为匿名函数

matlabFunction函数的调用语法有下面两种:

ht = matlabFunction(f)
ht = matlabFunction(f1,...,fN)

可以是一个sym对象,也可以是多个sym对象。前一种情况得到一个输出量个数为1的函数句柄,后一种情况下达到一个输出量个数为N的函数句柄。

这个函数句柄可以直接调用,得到数值结果。

>> syms x y z
f = x^2 + y^2 + z^2;
>> 
>> ht = matlabFunction(f)

ht =

  包含以下值的 function_handle:

    @(x,y,z)x.^2+y.^2+z.^2

多输出函数句柄的例子。

>> syms g(a, b, c)
>> g(a,b,c) = a + b + c
 
g(a, b, c) =
 
a + b + c
 
>> ht = matlabFunction(f, g)

ht =

  包含以下值的 function_handle:

    @(a,b,c,x,y,z)deal(x.^2+y.^2+z.^2,a+b+c)

这里得到的匿名函数,利用deal函数,可以得到多个输出量。

>> ht(1,2,3,4,5,6)
错误使用 deal
输入的数目应与输出的数目匹配。

出错 symengine>@(a,b,c,x,y,z)deal(x.^2+y.^2+z.^2,a+b+c)


>> [x1, x2] = ht(1,2,3,4,5,6)

x1 =

    77



x2 =

     6

进阶调用:转化为函数文件

matlabFunction函数还有一种调用方式,可以把符号表达式转化为函数文件。

matlabFunction(f, 'File', 'myfun1');
matlabFunction(f, g, 'File', 'myfun2');

这样就会在当前目录下生成一个myfun1.m文件,这个文件就是一个函数文件,可以直接调用。

function f = myfun1(x,y,z)
%MYFUN1
%    F = MYFUN1(X,Y,Z)

%    This function was generated by the Symbolic Math Toolbox version 23.2.
%    2024-10-19 23:19:02

f = x.^2+y.^2+z.^2;
end

对应着myfun2.m文件。

function [f,g] = myfun2(a,b,c,x,y,z)
%MYFUN2
%    [F,G] = MYFUN2(A,B,C,X,Y,Z)

%    This function was generated by the Symbolic Math Toolbox version 23.2.
%    2024-10-19 23:19:02

f = x.^2+y.^2+z.^2;
if nargout > 1
    g = a+b+c;
end
end

这就是两个非常普通的函数文件,可以直接调用。

其他转换时考虑向量、矩阵、稀疏矩阵等复杂情况,可以参考Matlab的文档。

实际应用

我们有一个分段函数,想推导其导数,然后在数值计算中能够同时求得其值和导数。

syms p(x)
p(x)  = piecewise(x<0, x^2-8, x>=0, -x)

这个函数的图像很容得到:

fplot(p, [-10, 10])

在这里插入图片描述

那么我们牢记前面的步骤,先推导,输出函数文件。


dp = diff(p, x);

matlabFunction(p, dp, 'File', 'piecewiseFunc');

这样就得到了一个函数文件piecewiseFunc.m,这个文件可以直接调用。

function [p,dp] = piecewiseFunc(x)
%piecewiseFunc
%    [P,DP] = piecewiseFunc(X)

%    This function was generated by the Symbolic Math Toolbox version 23.2.
%    2024-10-19 23:42:41

t2 = (x < 0.0);
if ~all(cellfun(@isscalar,{t2,x}))
    error(message('symbolic:sym:matlabFunction:ConditionsMustBeScalar'));
end
if (t2)
    p = x.^2-8.0;
elseif (0.0 <= x)
    p = -x;
else
    p = NaN;
end
if nargout > 1
    if ~all(cellfun(@isscalar,{t2,x}))    error(message('symbolic:sym:matlabFunction:ConditionsMustBeScalar'));end;if (t2)    dp = x.*2.0;elseif (0.0 < x)    dp = -1.0;else    dp = NaN;end;
end
end

唯一的问题是,这个函数不能直接针对向量调用,因此可以再包上一层。

function [p, dp] = piecewiseFuncVec(x)
    [p, dp] = arrayfun(@piecewiseFunc, x);
end

到这里,我们就得到了想要的函数,可以直接调用。

x = -10:0.1:10;
[p, dp] = piecewiseFuncVec(x);

tiledlayout(2,1)
nexttile
plot(x, p)
nexttile
plot(x, dp)

这样就可以得到这个函数的图像和导数的图像。

在这里插入图片描述

总结

  1. 一定要分离符号计算和数值计算,以免符号计算的低效影响数值计算的效率。
  2. fplot函数可以直接绘制符号表达式的图像。
  3. 符号函数是符号表达式的一种,可以直接调用,定义的方式为syms f(x,y,z); f(x, y, z)=...
  4. 符号表达式可以通过matlabFunction函数转化为函数句柄或者函数文件,这样就可以在数值计算中使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2219015.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

64页精品PPT | 汽车经销商数据应用解决方案

汽车经销商正面临前所未有的盈利能力挑战。从18年起 &#xff0c;传统燃油车汽车行业开始步入低速增长阶段 &#xff0c;卖车已经挣不到钱 &#xff0c;利润往往来自任务完成的厂家返利&#xff1b;新兴的直营模式的出现 &#xff0c;冲击了传统授权经销的方式 &#xff0c;疫情…

车辆管理新篇章:SpringBoot技术解析

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

sns数据分析

探索性数据分析 这一部分目的在于了解数据&#xff0c;包括数据是什么类型&#xff0c;数据有什么特点 数据信息 print(data.shape) data.info()(1086, 12) <class pandas.core.frame.DataFrame> Index: 1086 entries, 2020/7/1 0:00 to nan Data columns (total 12 c…

鸿蒙网络编程系列24-Web组件与应用互操作示例

1. APP内嵌网页与应用互操作概述 在通常的APP开发中&#xff0c;经常会采用内嵌网页的形式&#xff0c;通过网页来展现丰富的动态内容&#xff0c;虽少了很多原生开发的功能&#xff0c;但是这么做无可厚非&#xff0c;毕竟APP需要适配的系统平台很多&#xff0c;比如安卓、苹…

leetcode289:生命游戏

根据 百度百科 &#xff0c; 生命游戏 &#xff0c;简称为 生命 &#xff0c;是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子的面板&#xff0c;每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态&#xff1a; 1 即为 活细胞 &am…

babylonjs shader学习之copy shadertoy案例

shadertoy案例&#xff1a; 准备 const onSceneReady (scene: Scene) > {const light new HemisphericLight(light, new Vector3(0, 1, 0), scene);light.intensity 0.7;Effect.ShadersStore[planeMatVertexShader] precision highp float;attribute vec3 position;attr…

SpringMVC一个拦截器和文件上传下载的完整程序代码示例以及IDEA2024部署报错 找不到此 Web 模块的 out\artifacts\..问题

一、SpringMVC一个拦截器和文件上传下载的完整程序代码示例 本文章是一个 SpringMVC拦 截器和文件上传下载的完整程序代码示例&#xff0c;使用的开发工具是 IntelliJ IDEA 2024.1.6 (Ultimate Edition)&#xff0c; 开发环境是 OpenJDK-21 java version 21.0.2。Tomcatt版本为…

Flux.concat 使用说明书

public static <T> Flux<T> concat(Iterable<? extends Publisher<? extends T>> sources)Concatenate all sources provided in an Iterable, forwarding elements emitted by the sources downstream. 连接可迭代集合中提供的所有源&#xff0c;将…

【web】JDBC

项目连接数据库 右侧导航栏找到databsae 如果没有驱动&#xff0c;先下载驱动 填写数据库用户名密码 勾选对应的表即可 JDBC代码流程 1,配置信息 2,加载驱动 从MySQL Connector/J 5.1版本开始&#xff0c;推荐使用com.mysql.cj.jdbc.Driver这个新的驱动类。 3,链接数据库…

【MR开发】在Pico设备上接入MRTK3(三)——在Unity中运行MRTK示例

在前面的文档中&#xff0c;介绍了如何在Unity工程中配置号MRTK和Pico SDK 【MR开发】在Pico设备上接入MRTK3&#xff08;一&#xff09;在Unity中导入MRTK3依赖【MR开发】在Pico设备上接入MRTK3&#xff08;二&#xff09;在Unity中配置Pico SDK 本文将介绍如何运行一个简单…

SQL进阶技巧:如何找出开会时间有重叠的会议室?| 时间区间重叠问题

目录 0 场景描述 1 数据准备 2 问题分析 方法1:利用 lateral view posexplode()函数将表展开成时间明细表 方法2:利用数学区间讨论思想求解 3 小结 0 场景描述 有7个会议室,每个会议室每天都有人开会,某一天的开会时间如下: 查询出开会时间有重叠的是哪几个会议室?…

Agentic RAG(基于智能体的检索增强生成)是检索增强生成(Retrieval-Augmented Generation,RAG)技术的一种高级形式

Agentic RAG&#xff08;基于智能体的检索增强生成&#xff09;是检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;技术的一种高级形式&#xff0c;它通过引入人工智能代理&#xff08;Agent&#xff09;的概念&#xff0c;为语言模型赋予了…

C#从零开始学习(用unity探索C#)(unity Lab1)

初次使用Unity 本章所有的代码都放在 https://github.com/hikinazimi/head-first-Csharp Unity的下载与安装 从 unity官网下载Unity Hub Unity的使用 安装后,注册账号,下载unity版本,然后创建3d项目 设置窗口界面布局 3D对象的创建 点击对象,然后点击Move Guzmo,就可以拖动…

018_FEA_Structure_Static_in_Matlab三维结构静力学分析

刹车变形分析 本示例展示了如何使用 MATLAB 软件进行刹车变形分析。 这个例子是Matlab官方PDE工具箱的第一个例子&#xff0c;所需要的数据文件都由Matlab提供&#xff0c;包括CAD模型文件。 步骤 1: 导入 CAD 模型 导入 CAD 模型&#xff0c;这里使用的是一个带有孔的支架模…

HTTP cookie 与 session

一种关于登录的场景演示 - B 站登录和未登录 问题&#xff1a;B 站是如何认识我这个登录用户的&#xff1f;问题&#xff1a;HTTP 是无状态&#xff0c;无连接的&#xff0c;怎么能够记住我&#xff1f; 一、引入 HTTP Cookie 定义 HTTP Cookie&#xff08;也称为 Web Cooki…

【最新华为OD机试E卷-支持在线评测】VLAN资源池(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

R语言复杂抽样调查数据统计描述和分析

gtsummary包中tbl_svysummary提供了统计描述&#xff1b;tableone包中的svyCreateTableOne提供了统计比较&#xff1b;原始描述和比较可以是有table1包。 #测试数据 library(survey) setwd("F://") data(Titanic) sur_des<-survey::svydesign(~1, data as.data.…

Leetcode—1117. H2O 生成【中等】(多线程)

2024每日刷题&#xff08;182&#xff09; Leetcode—1117. H2O 生成 C实现代码 class H2O { public:H2O() {sem_init(&hydrogenSem, 0, 1);sem_init(&oxygenSem, 0, 0);}~H2O() {sem_destroy(&hydrogenSem);sem_destroy(&oxygenSem);}void hydrogen(functio…

重学SpringBoot3-Spring WebFlux简介

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-Spring WebFlux简介 1. 什么是 WebFlux&#xff1f;2. WebFlux 与 Spring MVC 的区别3. WebFlux 的用处3.1 非阻塞 I/O 操作3.2 响应式编程模型3.3 更高…

机械视觉光源选型

光源是机器视觉系统的重要组成部分&#xff0c;直接影响到图像的质量&#xff0c;进而影响到系统的性 能。在一定程度上&#xff0c;光源的设计与选择是机器视觉系统成败的关键。光源最重要的功能就 是使被观察的图像特征与被忽略的图像特征之间产生最大的对比度&#xff0c;…