如和使用matlab进行求导 ,入门级教程

简介: 如和使用matlab进行求导 ,入门级教程

问题如图所示


运行结果如图


代码分析


% 定义样本数量
n = 500;

这行代码定义了一个变量 n,它代表样本数量。这个变量在后面的代码中会被用到。

% 将 s 和 z 取值范围分成子区间的个数
num_intervals = 40;

这行代码定义了一个变量 num_intervals,它代表将 s 和 z 取值范围分成的子区间个数。这个变量在后面的代码中也会被用到。

% 将取值范围 [0,1] 和 [-1,1] 等分为 num_intervals+1 个子区间,存储在一维数组 s_values 和 z_values 中
s_values = linspace(0, 1, num_intervals + 1);

这行代码利用 linspace 函数将取值范围 [0, 1] 等分为 num_intervals+1 个子区间,并将每个子区间的左端点作为一个 num_intervals+1 长度的一维数组 s_values 中的元素。

% 将取值范围 [0,1] 和 [-1,1] 等分为 num_intervals+1 个子区间,存储在一维数组 s_values 和 z_values 中z_values = linspace(-1, 1, num_intervals + 1);

这行代码利用 linspace 函数将取值范围 [-1, 1] 等分为 num_intervals+1 个子区间,并将每个子区间的左端点作为一个 num_intervals+1 长度的一维数组 z_values 中的元素。

% 输出 s 和 z 的取值范围
fprintf('s ranges from %.2f to %.2f\n', s_values(1), s_values(end));
fprintf('z ranges from %.2f to %.2f\n', z_values(1), z_values(end));

这行代码分别输出了 sz 的取值范围,使用了 fprintf 函数对字符串进行格式化输出

% 定义 r 和 g 函数
r = @(s) n / 4 * s;
g = @(z, s) 1.03 * (1 - exp(-1 * s)) * (1 + z.^2);

这两行代码定义了两个函数,分别为 rg。其中,r 是关于参数 s 的一次函数,g 是关于参数 zs 的一次函数。这里用到了匿名函数的语法。

% 定义 r 和 g 的一阶、二阶导数
r_prime = n / 4;
g_second = @(a, s, z) (1.03 * exp(-s) * (z.^2 - 1)) / ((1.03 * (1 - exp(-s)) + a).^3);

这两行代码定义了 rg 的一阶、二阶导数。r_prime 是一个常数,等于 n/4g_second 是一个与 sz 相关的函数,用了一个 lambda 表达式进行定义。

% 初始化 a_s_z 矩阵
a_s_z = zeros(num_intervals + 1);

这行代码初始化了一个 num_intervals+1 行、num_intervals+1 列的零矩阵 a_s_z,它将用来存储各个 sz 取值下求得的最小值点处的 a 值。

% 对每个区间端点使用梯度下降法计算最小值点处 a 的值for i = 1 : num_intervals + 1
    for j = 1 : num_intervals + 1
           % 计算在 a=0 时的 g''(n*a) 值
        g_second_0 = g_second(0, s_values(i), z_values(j));
        a = 0;
           % 进行梯度下降迭代,根据公式更新 a 直到收敛
        while true
            grad_s = r_prime * s_values(i) + g_second(a, s_values(i), z_values(j)) * (1.03 * exp(-s_values(i)) - a - 1.03);
            grad_z = 2 * z_values(j) * g_second(a, s_values(i), z_values(j));
            % 根据 i 和 j 的值判断更新 a 的方式
            if i == 1 && j == 1
                a = a - 0.0005 * grad_s;
            elseif i == 1
                a = a - 0.0005 * grad_z;
            elseif j == 1
                a = a - 0.0005 * grad_s;
            else
                a = a - 0.0005 * (grad_s + grad_z);
            end
              % 检查是否收敛
            if abs(g_second(a, s_values(i), z_values(j))) < 1e-10
                break
            end
        end
       % 将求得的 a 值存储到 a_s_z 矩阵中
        a_s_z(i, j) = a;
    end
end

这部分代码是最主要的部分,它使用了梯度下降法来求解每个子区间端点处对应的最小值点 a。具体来说,对于矩阵中的每个元素 a_s_z(i,j),首先计算在 a=0 时的 g''(n*a) 值,然后进行梯度下降迭代,根据公式更新 a 直到收敛(即 g''(n*a) 的绝对值小于一个很小的数)。在每次更新 a 时,需要分别计算在 s 方向和 z 方向上的梯度并进行更新,具体涉及到一些判断语句,因为对于矩阵中的每个边界点,梯度计算方式不同。最终,每个子区间端点处求得的 a 值都储存在 a_s_z 矩阵中。

% 使用 mesh 函数将 a_s_z 矩阵可视化为一个三维网格图
figure;
[X, Y] = meshgrid(s_values, z_values);
mesh(X, Y, a_s_z');
xlabel('s');
ylabel('z');
zlabel('a');
title('Mesh plot of a(s,z)');

这行代码使用 mesh 函数将 a_s_z 矩阵可视化为一个三维网格图。使用 meshgrid 函数生成一组坐标点 XY,然后将 a_s_z 矩阵的转置作为纵坐标值,传入 mesh 函数中即可。最后,添加坐标轴标签和图标题,完成可视化。


完整代码


% 定义样本数量
n = 500;
% 将 s 和 z 取值范围分成子区间的个数
num_intervals = 40;
% 将取值范围 [0,1] 和 [-1,1] 等分为 num_intervals+1 个子区间,存储在一维数组 s_values 和 z_values 中
s_values = linspace(0, 1, num_intervals + 1);
z_values = linspace(-1, 1, num_intervals + 1);
% 输出 s 和 z 的取值范围
fprintf('s 范围从 %.2f 到 %.2f\n', s_values(1), s_values(end));
fprintf('z 范围从 %.2f 到 %.2f\n', z_values(1), z_values(end));
% 定义 r 和 g 函数
r = @(s) n / 4 * s;
g = @(z, s) 1.03 * (1 - exp(-1 * s)) * (1 + z.^2);
% 定义 r 和 g 的一阶、二阶导数
r_prime = n / 4;
g_second = @(a, s, z) (1.03 * exp(-s) * (z.^2 - 1)) / ((1.03 * (1 - exp(-s)) + a).^3);
% 初始化 a_s_z 矩阵
a_s_z = zeros(num_intervals + 1);
% 对每个区间端点使用梯度下降法计算最小值点处 a 的值
for i = 1 : num_intervals + 1
    for j = 1 : num_intervals + 1
        % 计算在 a=0 时的 g''(n*a) 值
        g_second_0 = g_second(0, s_values(i), z_values(j));
        a = 0;
        % 进行梯度下降迭代,根据公式更新 a 直到收敛
        while true
            grad_s = r_prime * s_values(i) + g_second(a, s_values(i), z_values(j)) * (1.03 * exp(-s_values(i)) - a - 1.03);
            grad_z = 2 * z_values(j) * g_second(a, s_values(i), z_values(j));
            % 根据 i 和 j 的值判断更新 a 的方式
            if i == 1 && j == 1
                a = a - 0.0005 * grad_s;
            elseif i == 1
                a = a - 0.0005 * grad_z;
            elseif j == 1
                a = a - 0.0005 * grad_s;
            else
                a = a - 0.0005 * (grad_s + grad_z);
            end
            % 检查是否收敛
            if abs(g_second(a, s_values(i), z_values(j))) < 1e-10
                break
            end
        end
        % 将求得的 a 值存储到 a_s_z 矩阵中
        a_s_z(i, j) = a;
    end
end
% 使用 mesh 函数将 a_s_z 矩阵可视化为一个三维网格图
figure;
[X, Y] = meshgrid(s_values, z_values);
mesh(X, Y, a_s_z');
xlabel('s');
ylabel('z');
zlabel('a');
title('a(s,z) 的网格图');


完结撒花

相关文章
|
7月前
【Simulink】示波器图形数据导入Matlab重新绘图的简明教程(论文)
【Simulink】示波器图形数据导入Matlab重新绘图的简明教程(论文)
|
7月前
【MATLAB】全网入门快、免费获取、持续更新的科研绘图教程系列1
【MATLAB】全网入门快、免费获取、持续更新的科研绘图教程系列1
142 0
【MATLAB】全网入门快、免费获取、持续更新的科研绘图教程系列1
|
1月前
|
Python Windows
SciPy 教程 之 SciPy Matlab 数组 1
本教程介绍了如何使用 SciPy 的 `scipy.io` 模块处理 Matlab 数组。通过 `savemat()` 方法可以将数据导出为 Matlab 格式的文件,而 `loadmat()` 方法则用于从 Matlab 文件中导入数据。示例展示了如何导出和导入一维数组,并解决了导入时数组维度增加的问题。
20 1
|
4月前
|
Go C++ Windows
Matlab 冰壶仿真游戏安装及教程
在Matlab上安装并运行冰壶仿真游戏的详细教程,包括编译环境准备、通过APP安装或直接运行源代码的方式,以及游戏的基本操作步骤。
44 0
|
6月前
|
算法 数据可视化 数据挖掘
大学生必备!GitHub星标破千的matlab教程(从新手到骨灰级玩家)
MATLAB(Matrix Laboratory)是MathWorks公司推出的用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境的商业数学软件。 MATLAB具有数值分析、数值和符号计算、工程与科学绘图、数字图像处理、财务与金融工程等功能,为众多科学领域提供了全面的解决方案。
|
6月前
|
算法 数据可视化 数据挖掘
大学生必备!GitHub星标破千的matlab教程(从新手到骨灰级玩家)
MATLAB(Matrix Laboratory)是MathWorks公司推出的用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境的商业数学软件。 MATLAB具有数值分析、数值和符号计算、工程与科学绘图、数字图像处理、财务与金融工程等功能,为众多科学领域提供了全面的解决方案。
|
6月前
|
数据可视化 数据挖掘 计算机视觉
Matlab教程:入门指南
Matlab教程:入门指南
|
7月前
MATLAB2022安装下载教程
MATLAB2022安装下载教程
871 2
|
7月前
|
编解码 移动开发 资源调度
【MATLAB】全网入门快、免费获取、持续更新的科研绘图教程系列1
【MATLAB】全网入门快、免费获取、持续更新的科研绘图教程系列1
95 0
|
7月前
第三章:MATLAB基础教程:控制流程和条件语句
第三章:MATLAB基础教程:控制流程和条件语句
77 0

热门文章

最新文章