MATLAB 之 函数文件、特殊形式的函数和程序调试与优化

文章目录

  • 一、函数文件
    • 1. 函数文件的基本结构
    • 2. 函数调用
      • 2.1 函数调用的格式
      • 2.2 函数的递归调用
      • 2.3 函数参数的可调性
      • 2.4 全局变量与局部变量
  • 二、特殊形式的函数
    • 1. 子函数
    • 2. 内联函数
    • 3. 匿名函数
  • 三、程序调试与优化
    • 1. 程序调试方法
      • 1.1 利用调试函数进行程序测试
      • 1.2 利用调试工具进行调试
    • 2. 程序性能分析与优化
      • 2.1 程序性能分析
      • 2.2 程序优化

一、函数文件

  • 我们在许多时候希望将特定的算法写成函数的形式,以提高程序的可重用性和程序设计的效率。
  • 函数文件定义了输出参数和输入参数的对应关系,以方便外部调用。事实上,MATLAB 提供的标准函数都是由函数文件定义的。

1. 函数文件的基本结构

  • 函数文件由 function 语句引导,其基本结构如下:
function 输出形参表=函数名(输入形参表)
注释说明部分
函数体语句
  • 其中,以 function 开头的一行为引导行,表示定义一个函数。函数名的命名规则与变量名相同。
  • 在函数定义时,输入输出参数没有分配存储空间,所以称为形式参数,简称形参。当有多个形参时,形参之间用逗号分隔,组成形参表。当输出形参多于一个时,则应该用方括号括起来,构成一个输出矩阵。
  • 说明:
  • (1) 关于函数文件名。函数文件名通常由函数名再加上扩展名 .m 组成,不过函数文件名与函数名也可以不相同。当两者不同时,MATLAB 将忽略函数名,调用时使用函数文件名。为理解和记忆的方便,一般建议函数文件名和函数名统一。
  • (2) 关于注释说明部分。注释说明包括如下 3 部分内容。
  • ① 紧随函数文件引导行之后以 % 开头的第一注释行。这一行一般包括大写的函数文件名和函数功能简要描述,供 lookfor 关键词查询和 help 在线帮助用。
  • ② 第一注释行及之后连续的注释行。通常包括函数输入输出参数的含义及调用格式说明等信息,构成全部在线帮助文本。
  • ③ 与在线帮助文本相隔一空行的注释行。包括函数文件编写和修改的信息,如作者、修改日期、版本等内容,用于软件档案管理。
  • (3) 关于 return 语句。如果在函数文件中插入了 return 语句,则执行到该语句就结束函数的执行,程序流程转至调用该函数的位置。通常,在函数文件中也可不使用 return 语句,这时在被调用函数执行完成后自动返回。
  • 例如,我们写函数文件, 求半径为 r 的圆的面积和周长。
  • 函数文件如下:
function [s,p] = fcircle(r)
% CIRCLE calculate the area and perimeter of a circle of radii r
% r    圆半径
% s    圆面积
% p    圆周长
% 2023515日编

s=pi*r*r;
p=2*pi*r;
  • 将以上函数文件以文件名 fcircle.m 存盘,然后在 MATLAB 命令行窗口调用该函数。
>> [s,p]=fcircle(10)

s =

  314.1593


p =

   62.8319

  • 采用 help 命令或者 lookfor 命令可以显示出注释说明部分的内容,其功能和一般 MATLAB 函数的帮助信息是一致的。
  • 利用 help 命令可查询 fcircle 函数的注释说明。
>> help fcircle
  CIRCLE calculate the area and perimeter of a circle of radii r
  r    圆半径
  s    圆面积
  p    圆周长
  2023515日编

  • 再用 lookfor 命令在 MATLAB 的搜索路径中寻找并列出所有第一注释行包括指定关键词的文件。
>> lookfor perimeter
fcircle                        - CIRCLE calculate the area and perimeter of a circle of radii r

2. 函数调用

2.1 函数调用的格式

  • 函数文件建立好后,就可以调用该函数了,调用格式如下:
    [输出实参表]=函数名(输入实参表)
  • 在调用函数时,函数输入输出参数称为实际参数,简称实参。要注意的是,函数调用时各实参出现的顺序、个数,应与函数定义时形参的顺序、个数-致,否则会出错。函数调用时,先将实参传递给相应的形参,从而实现参数传递,然后再执行函数的功能。
  • 例如,我们利用函数文件, 实现直角坐标 ( x , y ) (x, y) (x,y) 与极坐标 ( ρ , θ ) (\rho,\theta) (ρ,θ) 之间的转换 ρ = x 2 + y 2 \rho =\sqrt{x^{2}+y^{2}} ρ=x2+y2 θ = arctan ⁡ ( y / x ) \theta =\arctan (y/x) θ=arctan(y/x)
  • 首先编写函数文件 tran.m。
function [rho,theta] = tran(x,y)
rho=sqrt(x*x+y*y);
theta=atan(y/x);
end
  • 再在脚本文件中调用函数文件 tran.m。
x=input('x= ');
y=input('y=? ');
[rho,theta]=tran(x,y);
disp(['rho=',num2str(rho)])
disp(['theta=',num2str(theta)])
  • 最后在命令行窗口运行脚本文件。
x= 45
y= 45
rho=63.6396
theta=0.7854
  • 实际上,MATLAB 提供了直接坐标与极坐标之间转换的函数,分别如下:
  • (1) [th,r]=cart2pol(x,y) 是将直角坐标转换为极坐标。
  • (2) [x,y]=pol2cart(th,r) 是将极坐标转换为直角坐标。

2.2 函数的递归调用

  • 在 MATLAB 中,函数可以嵌套调用,即一个函数可以调用其他函数,甚至可以调用它自身。当一个函数调用它自身时称为函数的递归调用。
  • 例如,我们利用函数的递归调用,求 n ! n! n!
  • n ! n! n! 本身就是以递归的形式定义的: n ! = { 1 , n ≤ 1 n ( n − 1 ) ! , n > 1 n!=\left\{\begin{matrix}1,n≤1 \\n(n-1)!,n>1 \end{matrix}\right. n!={1n1n(n1)!n1
  • 显然,求 n ! n! n! 需要求 ( n − 1 ) ! (n-1)! (n1)!,这时可采用递归调用。采用递归调用的函数文件 factor.m 如下:
function f=factor(n)
if n<1
    f=1;
else
    f=factor(n-1)*n;  %递归调用求(n-1)!
end
  • 在脚本文件中调用函数文件 factor.m,求 s = 1 ! + 2 ! + 3 ! + 4 ! + 5 ! s=1!+2!+3!+4!+5! s=1!+2!+3!+4!+5!
s=0;
n=input('n= ');
for i=1:n
    s=s+factor(i);
end
disp(['从1到',num2str(n),'的阶乘和为:', num2str(s)])
  • 在命令行窗口运行脚本文件:
n= 515的阶乘和为:153
  • 任意排列问题。MATLAB 提供的函数 randperm(n) 可以产生一个从整数 1 到整数 n 的任意排列。编写一个函数来实现 randperm(n) 函数的功能,即给出一个由任意数组成的行向量,然后产生这个行向量元素的任意排列。
  • 考虑编写两个不同的函数,这两个函数的功能完全相同,只是控制结构不同。第一个函数用循环结构,可以用 for 语句或 while 语句控制循环,第二个函数使用递归调用。
  • (1) 函数用循环结构。
function Y=rndprm1(X)
%RNDPRM1 用for循环产生一个行向量的任意排列
%rndprm1(X)产生行向量X的任意排列
[m,n]=size(X);
if m>1
    error('RNDPRM1 accepts as inputs only vectors');
end
Y=[];  %从一个空矩阵开始
l=n;  %X的元素个数
for i=1:n
    k=1+fix(1*rand);    %随机选择Y的下一个元素的位置
    x=X(k);  %被选择的元素
    Y=[Y,x];  %将x添加到Y中
    X(k)=[];  %从X中删除x
    l=l-1;  %更新X的元素个数
end
  • (2) 函数用递归调用。
function Y=rndprm2(X)
%RNDPRM2 用for循环产生一个行向量的任意排列
%rndprm2(X)产生行向量X的任意排列
[m,n]=size(X);
l=n;
if m>1
    error('RNDPRM2 accepts as inputs only vectors');
end
if n<=1
    Y=X;
else
    k=1+fix(1*rand);    %随机选择Y的下一个元素的位置
    x=X(k);  %被选择的元素
    X(k)=[];  %从X中删除x
    Z=rndprm2(X);  %将剩下的元素随机排列
    Y=[Z,x];  %构造输出向量
    l=l-1;  %更新X的元素个数
end
  • (3) 在命令行窗口调用所定义的函数,命令如下:
>> rndprm1([34,6,3,54,2,5,454])

ans =

    34     6     3    54     2     5   454

>> rndprm2([34,6,3,54,2,5,454])

ans =

   454     5     2    54     3     6    34

  • 因为 MATLAB 将长度为n的字符串当作一个长度为 n 的向量,所以也可以用字符串作为函数的自变量。例如:
>> rndprm1('apple')

ans =

    'apple'

>> rndprm2('apple')

ans =

    'elppa'

2.3 函数参数的可调性

  • MATLAB 在函数调用上有一个特点,就是函数所传递参数数目的可调性。凭借这一点,一个函数可完成多种功能。
  • 在调用函数时,MATLAB 用两个预定义变量 nargin 和 nargout 分别记录调用该函数时的输入实参和输出实参的个数。只要在函数文件中包含这两个变量,就可以准确地知道该函数文件被调用时的输入/输出参数个数,从而决定函数如何进行处理。
  • nargin 用法示例。
  • 建立函数文件 charray.m。
function fout=charray(a,b,c)
if nargin==1
    fout=a;
elseif nargin==2
    fout=a+b;
elseif nargin==3
    fout=(a*b*c)/2;
end
  • 建立脚本文件 mydemo.m。
a=1:3;
b=a';
x=charray(a);
y=charray(a,b');
z=charray(a,b,3);
disp(['x=    ',num2str(x)])
disp(['y=    ',num2str(y)])
disp(['z=    ',num2str(z)])
  • 执行脚本文件 mydemo.m 后的输出结果如下:
x=    1  2  3
y=    2  4  6
z=    21
  • 在脚本文件 mydemo.m 中,3 次调用函数文件 charray.m,因输入参数分别是 1、2、3,从而执行不同的操作,返回不同的函数值。

2.4 全局变量与局部变量

  • 在 MATLAB 中,函数文件中的变量是局部的,与其他函数文件及 MATLAB 工作空间相互隔离,即在一个函数文件中定义的变量不能被另一个函数文件引用。
  • 如果在若干函数中,都把某一变量定义为全局变量,那么这些函数将共用这个变量。全局变量的作用域是整个 MATLAB 工作空间,即全程有效,所有的函数都可以对它进行存取和修改,因此,定义全局变量是函数间传递信息的一种手段。
  • 全局变量用 global 命令定义,格式如下:
    global变量名
  • 全局变量应用示例。
  • 先建立函数文件 wadd.m,该函数将输入的参数加权相加。
function f=wadd(x,y)
global ALPHA BETA
f=ALPHA*x+BETA*y;
  • 在命令行窗口中输入命令并得到输出结果。
>> global ALPHA BETA
>> ALPHA=1;
>> BETA=2;
>> s=wadd(1,2)

s =

     5

  • 由于在函数 wadd 和基本工作空间中都把 ALPHA 和 BETA 两个变量定义为全局变量,所以只要在命令行窗口中改变 ALPHA 和 BETA 的值,就可改变函数中 x、y 的权值,而无须修改 wadd.m 文件。
  • 在实际程序设计时,可在所有需要调用全局变量的函数中定义全局变量,这样就可实现数据共享。在函数文件中,全局变量的定义语句应放在变量使用之前,为了便于了解所有的全局变量,一般把全局变量的定义语句放在文件的前部。为了在工作空间中使用全局变量,也要定义全局变量。
  • 值得指出的是,在程序设计中,全局变量固然可以带来某些方便,但却破坏了函数对变量的封装,降低了程序的可读性,因此,在结构化程序设计中,全局变量是不受欢迎的,尤其当程序较大,子程序较多时,全局变量将给程序调试和维护带来不便,故不提倡使用全局变量。如果一定要用全局变量,最好给它起-一个能反映变量含义的名字,以免和其他变量混淆。

二、特殊形式的函数

  • 除了最常用的通过函数文件定义一个函数,MATLAB 还可以使用子函数,此外还可以通过内联函数和匿名函数自定义函数。

1. 子函数

  • 在 MATLAB 的函数定义中,如果函数较长,往往可以将多个函数分别写在不同的函数文件中,但有时函数可能很短,可能希望将多个函数定义放在同一个函数文件中,这就存在子函数的定义问题。
  • 在 MATLAB 中,可以在一个函数文件中同时定义多个函数,其中函数文件中出现的第一个函数称为主函数(Primary Function),其他函数称为子函数(Subfunction),但需要注意的是子函数只能由同一函数文件中的函数调用。
  • 在保存函数文件时,函数文件名一般和主函数名相同,外部程序只能对主函数进行调用。例如建立 func.m 文件,程序如下。
function d=func(a,b,c)  %主函数
d=subfunc(a,b)+c;
function c=subfunc(a,b)  %子函数,此c非彼c,这里的c是形式输出变量
c=a*b;
  • 在命令行窗口调用主函数,结果如下:
>> func(3,4,5)

ans =

    17

  • 注意,同一函数文件中主函数和子函数的工作区是彼此独立的,各个函数间的信息传递可以通过输入输出参数、全局变量来实现。

2. 内联函数

  • 以字符串形式存在的函数表达式可以通过 inline 函数转化为内联函数。例如 a=‘(x+y)^2’,可以通过 f=inline(a) 生成内联函数 f(x,y)=(x+y)^2。
>> a='(x+y)^2';
>> f=inline(a)

f =

     内联函数:
     f(x,y) = (x+y)^2

>> f(3,4)

ans =

    49

3. 匿名函数

  • 匿名函数的基本格式如下:
    函数句柄变量=@ (匿名函数输入参数)匿名函数表达式
  • 其中,函数句柄变量相当于函数的别名,利用它可以间接调用函数;“@” 是创建函数句柄的运算符;“@” 后面定义了一个匿名函数,包括函数输入参数和函数表达式;函数有多个输入参数时,参数间用逗号分隔。例如:
>> sqr=@(x) x.^2  %定义匿名函数

sqr =

  包含以下值的 function_handle:

    @(x)x.^2

>> sqr([1,2,3])  %调用匿名函数

ans =

     1     4     9

>> f=@(x,y) x^2+y^2;
>> f(3,4)

ans =

    25

  • 也可以通过下列语句给已存在的函数定义函数句柄,并利用函数句柄来调用函数。
    函数句柄变量=@函数名
  • 其中,函数名可以是 MATLAB 提供的内部函数,也可以是用户定义的函数文件。例如:
>> h=@sin  %8取正弦函数句柄

h =

  包含以下值的 function_handle:

    @sin

>> h(pi/2) %通过函数句柄变量h来调用正弦函数

ans =

     1

  • 匿名函数的执行效率要明显高于内联函数,在参数传递方面也要比内联函数方便、高效。内联函数在将来的MATLAB版本中将被删除,取而代之的是匿名函数,内联函数能实现的,匿名函数完全可以更好地实现,并且调用效率要比内联函数高得多。

三、程序调试与优化

  • 程序调试(Debug)是程序设计的重要环节,MATLAB 提供了相应的程序调试功能,既可以通过 MATLAB 编辑器对程序进行调试,又可以在命令行窗口结合具体的命令进行。
  • 程序设计的思路是多种多样的,针对同样的问题可以设计出不同的程序,而不同的程序其执行效率会有很大不同,特别是数据规模很大时,差别尤为明显,所以,有时需要借助于性能分析工具分析程序的执行效率,并充分利用 MATLAB 的特点,对程序进行优化,从而达到提高程序性能的目的。

1. 程序调试方法

  • 一般来说,应用程序的错误有两类,一类是语法错误,另一类是运行时的错误。MATLAB 能够检查出大部分的语法错误,给出相应错误信息,并标出错误在程序中的行号。程序运行时的错误是指程序的运行结果有错误,这类错误也称为程序逻辑错误。
  • MATLAB 系统对逻辑错误是无能为力的,不会给出任何提示信息,这时可以通过一些调试方法来发 现程序中的逻辑错误。

1.1 利用调试函数进行程序测试

  • MATLAB 提供了一系列的程序调试函数,用于程序执行过程中的断点操作、执行控制等。在 MATLAB 命令行窗口输入以下命令将输出调试函数及其用途简介。
>> help debug
  • 常用的调试函数有以下几个。
  • (1) dbstop:在程序的适当位置设置断点,使得系统在断点前停止执行,用户可以检查各个变量的值,从而判断程序的执行情况,帮助发现错误。使用以下命令可以显示 dbstop 函数的常用格式。
>> help dbstop
  • (2) dbclear:清除用 dbstop 函数设置的断点。
  • (3) dbcont:从断点处恢复程序的执行,直到遇到程序的其他断点或错误。
  • (4) dbstep:执行一行或多行语句,执行完后返回调试模式,如果在执行过程中遇到断点,程序将中止。
  • (5) dbquit:退出调试模式并返回到基本工作区,所有断点仍有效。

1.2 利用调试工具进行调试

  • 在 MATLAB 编辑器中新建一个 M 文件或打开一个 M 文件时,编辑器选项卡提供了断点命令组,通过对 M 文件设置断点可以使程序运行到某一行暂停运行, 这时可以查看和修改工作区中的变量。
  • 单击断点命令按钮,弹出下拉菜单,其中有 6 个命令,分别用于清除所有断点,设置/清除断点,启用/禁用断点,设置或修改条件断点(条件断点可以使程序执行到满足一定条件时停止),出现错误时停止(不包括 try…catch 语句中的错误),出现警告时停止。
  • 在 M 文件中设置断点并运行程序,程序即进入调试模式,并运行到第一个断点处,此时编辑器选项卡上出现调试命令组,命令行窗口的提示符相应变成 K>>。
  • 进入调试模式后,最好将编辑器窗口锁定,即停靠到 MATLAB 主窗口上,便于观察代码运行中变量的变化。要退出调试模式,则在调试命令组中单击退出调试按钮。
  • 控制单步运行的命令共有 4 个。在程序运行之前,有些命令按钮未激活。只有当程序中设置了断点,且程序停止在第一个断点处时这些命令按钮才被激活,这些命令按钮功能如下。
  • (1) 步进:单步运行。每单击一次,程序运行一条语句,但不进入函数。
  • (2) 步入:单步运行。遇到函数时进入函数内,仍单步运行。
  • (3) 步出:停止单步运行。如果是在函数中,跳出函数;如果不在函数中,直接运行到下一个断点处。
  • (4) 运行到光标处:直接运行到光标所在的位置。

2. 程序性能分析与优化

2.1 程序性能分析

  • 利用探查器(Profiler)、 tic 函数和 toc 函数能分析程序各环节的耗时情况,分析报告能帮助用户寻找影响程序运行速度的瓶颈所在,以便于进行代码优化。
  • 探查器以图形化界面让用户深入地了解程序执行过程中各函数及函数中的每条语句所耗费的时间,从而有针对性地改进程序,提高程序的运行效率。
  • 假定有脚本文件 testp.m:
x=-20:0.1:20;
y=300*sin(x)./x;
plot(x,y);
  • 在 MATLAB 的命令行窗口输入以下命令:
>> profile on
>> testp
>> profile viewer
  • 这时,MATLAB 将打开探查器窗口,显示分析结果。探查摘要表提供了运行文件的时间和相关函数的调用频率,反映出整个程序耗时 2.626s,其中绘制图形中调用的 newplot 函数耗时最多。单击某函数名,则打开相应函数的详细报告。

在这里插入图片描述

2.2 程序优化

  • MATLAB 是解释型语言,计算速度较慢,所以在程序设计时如何提高程序的运行速度是需要重点考虑的问题。优化程序运行可采用以下方法。
  • (1) 采用向量化运算。在实际 MATLAB 程序设计中,为了提高程序的执行速度,常用向量或矩阵运算来代替循环操作。首先生成一个向量 i i i,然后用 i i i 生成向量 f f f f f f 各元素值即对应于 y y y 的各累加项,再用 MATLAB 提供的 sum 函数求f各个元素之和。程序如下:
n=100;
i=1:n;
f=1./(i.*i);
y=sum(f)
  • 如果程序中的 n 值由 100 改成 100000,再分别运行这两个程序,则可以明显地看出,用向量计算方法编写的程序比循环程序要快得多。
  • (2) 预分配内存空间。通过在循环之前预分配向量或数组的内存空间可以提高 for 循环的处理速度。例如,下面的代码用函数 zeros 预分配 for 循环中用到的向量 a 的内存空间,使得这个 for 循环的运行速度显著加快。
  • 程序 1:
clear;
a=0;
for n=2:1000
    a(n)=a(n-1)+10;
end
  • 程序 2:
clear;
a=zeros(1,1000);
for n=2:1000
    a(n)=a(n-1)+10;
end
  • 程序 2 采用了预定义矩阵的方法,运行时间比程序 1 要短。
  • (3) 减小运算强度。在实现有关运算时,尽量采用运算量更小的运算,从而提高运算速度。一般来说,乘法比乘方的运算快,加法比乘法运算快。例如:
clear;
a=rand(32);  %生成一个32×32矩阵
x=a.^3;
y=a.*a.*a;
  • 从 Profiler 的评估报告中可以看出,a.*a.*a 比 a.^3 运算所花的时间少得多。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL数据库,JDBC连接数据库操作流程详细介绍

前言&#xff1a; 在学完 MySQL 和 Java 后&#xff0c;我们通常会尝试使用 Java编译器 连接 MySQL数据库&#xff0c;从而达到使用编译器来操作数据库的效果。连接的这个过程会用 JDBC 相关知识&#xff0c;因此我把 JDBC 包的下载及导入流程&#xff0c;以及 JDBC 的使用流程…

1.Buffer_Overflow-1.Basic_Jump

github上面的练习题 git clone https://github.com/Adamkadaban/LearnPwn 然后开始做 先进行 readelf 然后进行执行看看 是怎么回事 ./buf1发现就是一个输入和输出 我们checksec看看 发现stack 保护关闭 开启了NX保护 我们进入ida64看看反汇编 我习惯先看看字符串 SHITF…

C#异步编程之数据并行及任务并行

基于Parallel.ForEach的数据并行使用 1.数据非并行 var items new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; DateTime t1 DateTime.Now; foreach (var item in items) {Console.WriteLine("数据非并行输出:{0}", item); } 2.数据并行,只要使用Parallel.ForEach P…

Docker高频使用命令总结(镜像与容器命令)

目录 一.Docker常用命令总结 1.镜像命令管理 2.容器命令管理 二.Docker镜像操作命令 1.docker search&#xff1a;搜索镜像 2.docker pull&#xff1a;下载镜像 3.docker push&#xff1a;上传镜像 4.docker images&#xff1a;查看本地镜像 5.docker inspect &#x…

360+ChatGLM联手研发中国版“微软+OpenAI”

文章目录 前言360与智谱AI强强联合什么是智谱AI360智脑360GLM与360GPT大模型战略布局写在最后 前言 5月16日&#xff0c;三六零集团&#xff08;下称“360”&#xff09;与智谱AI宣布达成战略合作&#xff0c;双方共同研发的千亿级大模型“360GLM”已具备新一代认知智能通用模…

Springboot——事物管理

文章目录 事务管理一、 Spring事务管理1.1 事务回顾1.2 案例&#xff1a; 解散部门&#xff08;未开启事务&#xff09;1.3 事务管理注解Transactional1.4 事务管理日志开关1.5 rollbackFor 异常回滚属性1.6 propagation 事务传播行为1.7 解散部门并记录操作日志1.7.1 创建数据…

技术探秘:揭秘Bean Factory与FactoryBean的区别!

大家好&#xff0c;我是小米&#xff0c;一个热衷于技术分享的29岁小编。今天&#xff0c;我们来聊一聊在Spring框架中常用的两个概念&#xff1a;beanFactory和FactoryBean。它们虽然看似相似&#xff0c;但实际上有着不同的用途和作用。让我们一起来揭开它们的神秘面纱吧&…

离散数学_九章:关系(6)

&#x1fa90;9.6 偏序 1、⛺偏序关系和偏序集⛲偏序关系⛲偏序&#xff08;关系&#xff09;的例子 a. “大于或等于” 关系b. “整除” 关系c. “包含” 关系 &#x1f3ac;偏序集&#x1f3ac;可比性&#xff08;comparability&#xff09; " ≼ " 符号a. 可比 &a…

基于野火F407骄阳开发板的苹果采摘机器人机械臂的采摘轨迹与夹持器的采摘动作的设计(1)

基于野火F407骄阳开发板的苹果采摘机器人机械臂的采摘轨迹与夹持器的采摘动作的设计&#xff08;1&#xff09; 苹果采摘机器人1、采摘流程与硬件设计2、机械臂驱动以及采摘轨迹设计2.1、台达A2电机驱动实现2.2、机械臂寻找苹果巡逻轨迹 苹果采摘机器人 1、采摘流程与硬件设计…

C++/Qt 小知识记录3

工作中遇到的一些小问题&#xff0c;总结的小知识记录&#xff1a;C/Qt 小知识 QLineEdit限制输入大于0的正整数QLayout内清空已布局的WidgetWindows结束进程直接结束&#xff0c;子进程不响应结束事件正常结束&#xff0c;子进程响应结束事件 CMake关闭控制台Console实体与值对…

尾调用优化

尾调用优化 最近遇到一个堆栈溢出的问题&#xff0c;分析后发现可收敛为递归边界问题。结合“红宝书”中相关内容和ES6规范中的一些优化机制&#xff0c;整理记录如下。 前言 程序运行时&#xff0c;计算机会为应用程序分配一定的内存空间。应用程序会自行分配所获得的内存空…

数组或结构体赋值时memcpy与直接赋值的效率比较

先上结论&#xff1a; 二者不一定谁快通常情况下&#xff0c;数组维度越大&#xff0c;使用memcpy效率更高数组维度越大&#xff0c;直接赋值耗时主体是循环耗时 Note&#xff1a; “等号赋值”被编译器翻译成一连串的MOV指令&#xff0c;而memcpy则是一个循环。“等号赋值”比…

深入解析PyTorch中的模型定义:原理、代码示例及应用

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

【一起啃书】《机器学习》第六章 支持向量机

文章目录 第六章 支持向量机6.1 间隔和支持向量6.2 对偶问题6.3 核函数6.4 软间隔与正则化6.5 支持向量回归6.6 核方法6.7 一些问题 第六章 支持向量机 6.1 间隔和支持向量 给定训练样本集 D { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) } , y i ∈ { − 1 , …

Day 1 认识软件测试——(软件测试定义、目的、原则)

Day 1 认识软件测试——(软件测试定义、目的、原则) 文章目录 Day 1 认识软件测试——(软件测试定义、目的、原则)软件测试的定义软件测试的目的软件测试的经济学问题黑盒测试白盒测试软件测试原则小结所谓软件测试,就是一个过程或一系列过程,用来确定计算机代码完成了其…

《我命由我不由天》蔡志忠——笔记一

目录 简介 经典摘录 三岁决定一生 父母该什么时候放手 确定将来要成为什么 积极主动为目标而努力 叛逆是最伟大的创意 父亲给蔡志忠最大的影响是教会他两件事 价值观缺陷导致的后果 人有三个阶段 简介 作者 蔡志忠&#xff0c;李虹。 蔡志忠&#xff1a;漫画家、哲…

Vue加SpringBoot实现项目前后端分离

首先需要搭建一个Vue的脚手架项目&#xff08;已经放在gitee里面了&#xff0c;下面是gitee网址&#xff0c;可以直接拉&#xff09; (vue-web: 这个是Vue项目模板&#xff0c;没有后台数据) 那么接下来就是实现前后端分离的步骤 首先我们需要有一个登录页面 登录的点击事件利用…

图神经网络:(节点分类)在KarateClub数据集上动手实现图神经网络

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook。超链。提取码8888。 文章目录 文献阅读&#xff1a;代码实操&#xff1a; 文献阅读&#xff1a; 参考文…

【Hello Algorithm】归并排序及其面试题

作者&#xff1a;小萌新 专栏&#xff1a;算法 作者简介&#xff1a;大二学生 希望能和大家一起进步 本篇博客简介&#xff1a;介绍归并排序和几道面试题 归并排序及其面试题 归并排序归并排序是什么归并排序的实际运用归并排序的迭代写法归并排序的时间复杂度 归并排序算法题小…

(十一)地理数据库创建——创建新的地理数据库

地理数据库创建——创建新的地理数据库 目录 地理数据库创建——创建新的地理数据库 1.地理数据库概述2.地理数据库建立一般过程2.1地理数据库设计2.2地理数据库建立2.2.1从头开始建立一个新的地理数据库2.2.2移植已经存在数据到地理数据库2.2.3用CASE工具建立地理数据库 2.3建…