1、Claude实现双曲正切函数图像绘制
Claude的代码能力真的很强!
基本上把需求告诉它,输出的代码都可以直接运行,基本不会报错;报错了就把错误再告诉它,就可以动态的看到它在修改代码,非常高效!
需求:想绘制双曲正切函数的图像,对比不同epslion取值的影响,给出matlab代码
% 双曲正切函数不同epsilon值的对比图像
% tanh(x/ε) = (e^(x/ε) - e^(-x/ε)) / (e^(x/ε) + e^(-x/ε))
clear; clc; close all;
% 定义x的范围
x = linspace(-10, 10, 1000);
% 定义不同的epsilon值
epsilon_values = [0.5, 1, 2, 5];
colors = ['r', 'b', 'g', 'm']; % 不同颜色
line_styles = {'-', '--', '-.', ':'}; % 不同线型
% 创建图形窗口
figure('Position', [100, 100, 800, 600]);
% 绘制不同epsilon值的双曲正切函数
hold on;
legend_entries = cell(length(epsilon_values), 1);
for i = 1:length(epsilon_values)
epsilon = epsilon_values(i);
% 计算双曲正切函数值
y = tanh(x / epsilon);
% 绘制曲线
plot(x, y, 'Color', colors(i), 'LineStyle', line_styles{i}, ...
'LineWidth', 2, 'DisplayName', ['\epsilon = ' num2str(epsilon)]);
legend_entries{i} = ['\epsilon = ' num2str(epsilon)];
end
% 设置图形属性
grid on;
xlabel('x', 'FontSize', 12, 'FontWeight', 'bold');
ylabel('tanh(x/\epsilon)', 'FontSize', 12, 'FontWeight', 'bold');
title('双曲正切函数 tanh(x/\epsilon) 在不同 \epsilon 值下的对比', ...
'FontSize', 14, 'FontWeight', 'bold');
% 设置坐标轴范围
xlim([-10, 10]);
ylim([-1.2, 1.2]);
% 添加水平参考线
plot([-10, 10], [1, 1], 'k--', 'LineWidth', 0.5);
plot([-10, 10], [-1, -1], 'k--', 'LineWidth', 0.5);
plot([-10, 10], [0, 0], 'k-', 'LineWidth', 0.5);
% 添加垂直参考线
plot([0, 0], [-1.2, 1.2], 'k-', 'LineWidth', 0.5);
% 设置图例
legend('Location', 'southeast', 'FontSize', 10);
% 添加注释说明epsilon的影响
text(-8, 0.8, {'\epsilon 越小,函数变化越陡峭', ...
'\epsilon 越大,函数变化越平缓'}, ...
'FontSize', 10, 'BackgroundColor', 'white', ...
'EdgeColor', 'black', 'Margin', 5);
hold off;
% 创建第二个子图显示导数对比
figure('Position', [200, 200, 800, 600]);
hold on;
for i = 1:length(epsilon_values)
epsilon = epsilon_values(i);
% 计算导数: d/dx[tanh(x/ε)] = (1/ε) * sech²(x/ε) = (1/ε) * (1 - tanh²(x/ε))
y_tanh = tanh(x / epsilon);
y_derivative = (1/epsilon) * (1 - y_tanh.^2);
% 绘制导数曲线
plot(x, y_derivative, 'Color', colors(i), 'LineStyle', line_styles{i}, ...
'LineWidth', 2, 'DisplayName', ['\epsilon = ' num2str(epsilon)]);
end
% 设置导数图的属性
grid on;
xlabel('x', 'FontSize', 12, 'FontWeight', 'bold');
ylabel('d/dx[tanh(x/\epsilon)]', 'FontSize', 12, 'FontWeight', 'bold');
title('双曲正切函数导数在不同 \epsilon 值下的对比', ...
'FontSize', 14, 'FontWeight', 'bold');
xlim([-10, 10]);
ylim([0, 2.5]);
% 添加参考线
plot([0, 0], [0, 2.5], 'k-', 'LineWidth', 0.5);
plot([-10, 10], [0, 0], 'k-', 'LineWidth', 0.5);
legend('Location', 'northeast', 'FontSize', 10);
% 添加注释
text(5, 2, {'\epsilon 越小,导数峰值越大', ...
'函数在原点附近变化越剧烈'}, ...
'FontSize', 10, 'BackgroundColor', 'white', ...
'EdgeColor', 'black', 'Margin', 5);
hold off;
% 显示epsilon对函数特性的数值分析
fprintf('双曲正切函数 tanh(x/ε) 的特性分析:\n');
fprintf('====================================\n');
for i = 1:length(epsilon_values)
epsilon = epsilon_values(i);
% 计算在x=0处的导数值(最大斜率)
max_slope = 1/epsilon;
% 计算达到90%饱和值时的x值
x_90_percent = epsilon * atanh(0.9);
fprintf('ε = %.1f: 最大斜率 = %.2f, 90%%饱和点 x ≈ ±%.2f\n', ...
epsilon, max_slope, x_90_percent);
end
以上就是Claude生成的代码,这是经过一次调试的,第一次输出的代码有点小问题。
第二次输出的代码非但没有问题,还增加了很多可视化的东西,例如 “添加参考线”、“添加注释”,这些功能都是我没有要求的,非常的amazing!
plot出来两幅图:
看完了双曲正切函数的图像,接下来就是看一下双曲正切函数的两个性质。
2、双曲正切函数的两个性质
引理1
证明过程如下:
这个证明过程非常简单。
引理2
引理2我大概知道是想说明有界,但是不知道怎么来的,于是乎我又问了Claude
以下是Claude给出的回答:
引理2的推导基于以下几个关键步骤:
核心思想:
函数定义:考虑函数 f(χ) = |χ| - χtanh(χ/ε) 对称性利用:由于tanh函数的奇偶性,只需分析 χ ≥ 0 的情况
最优化问题:寻找函数 g(t) = t(1-tanh(t)) 的最大值推导过程:
对于 χ ≥ 0:f(χ) = χ(1 - tanh(χ/ε)) = ε · (χ/ε)(1 - tanh(χ/ε)) 令 t =
χ/ε,则问题转化为求 g(t) = t(1-tanh(t)) 的最大值 通过求导 g’(t) = 1 - tanh(t) -
t·sech²(t) = 0 找到临界点 数值求解得到最大值约为 0.2785物理意义: 这个引理在控制理论中很重要,它给出了线性项 |χ| 与饱和非线性项 χtanh(χ/ε) 之间差值的精确界限。常数 μ = 0.2785 是通过严格的数学分析得出的最优界限。 运行上面的验证代码可以:
数值验证最大值确实是 0.2785 验证不等式对所有 χ 值都成立 展示不同 ε 值下的函数行为
Claude给出验证代码如下:
% 引理2的数值验证
% 验证: 0 ≤ |χ| - χ*tanh(χ/ε) ≤ μ*ε, μ = 0.2785
clear; clc; close all;
%% 第一部分:寻找函数 g(t) = t(1-tanh(t)) 的最大值
% 定义函数 g(t) = t(1-tanh(t))
g = @(t) t .* (1 - tanh(t));
% 定义导数 g'(t) = 1 - tanh(t) - t*sech^2(t)
g_prime = @(t) 1 - tanh(t) - t .* (sech(t)).^2;
% 寻找临界点(数值方法)
t_range = linspace(0, 5, 1000);
g_values = g(t_range);
[max_value, max_idx] = max(g_values);
t_optimal = t_range(max_idx);
fprintf('数值分析结果:\n');
fprintf('函数 g(t) = t(1-tanh(t)) 的最大值: %.6f\n', max_value);
fprintf('最大值点: t = %.6f\n', t_optimal);
fprintf('理论值 μ = 0.2785\n');
fprintf('相对误差: %.2f%%\n', abs(max_value - 0.2785)/0.2785 * 100);
%% 第二部分:绘制函数图像
figure('Position', [100, 100, 1200, 400]);
% 子图1: g(t) = t(1-tanh(t))
subplot(1,3,1);
t_plot = linspace(0, 4, 1000);
g_plot = g(t_plot);
plot(t_plot, g_plot, 'b-', 'LineWidth', 2);
hold on;
plot(t_optimal, max_value, 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r');
plot([0, 4], [0.2785, 0.2785], 'r--', 'LineWidth', 1);
grid on;
xlabel('t');
ylabel('g(t) = t(1-tanh(t))');
title('函数 g(t) = t(1-tanh(t))');
legend('g(t)', '最大值点', 'μ = 0.2785', 'Location', 'best');
% 子图2: 导数 g'(t)
subplot(1,3,2);
g_prime_plot = g_prime(t_plot);
plot(t_plot, g_prime_plot, 'g-', 'LineWidth', 2);
hold on;
plot([0, 4], [0, 0], 'k--', 'LineWidth', 0.5);
plot(t_optimal, 0, 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r');
grid on;
xlabel('t');
ylabel('g''(t)');
title('导数 g''(t)');
legend('g''(t)', 'y=0', '零点', 'Location', 'best');
%% 第三部分:验证不等式对任意χ成立
epsilon_test = 1; % 测试用的ε值
chi_range = linspace(-10, 10, 1000);
% 计算 f(χ) = |χ| - χ*tanh(χ/ε)
f_values = abs(chi_range) - chi_range .* tanh(chi_range / epsilon_test);
% 验证不等式
upper_bound = 0.2785 * epsilon_test;
is_valid = all(f_values >= 0) && all(f_values <= upper_bound);
% 子图3: 验证不等式
subplot(1,3,3);
plot(chi_range, f_values, 'b-', 'LineWidth', 2);
hold on;
plot(chi_range, upper_bound * ones(size(chi_range)), 'r--', 'LineWidth', 2);
plot(chi_range, zeros(size(chi_range)), 'k-', 'LineWidth', 0.5);
grid on;
xlabel('χ');
ylabel('|χ| - χtanh(χ/ε)');
title(['不等式验证 (ε = ', num2str(epsilon_test), ')']);
legend('f(χ)', '上界 μ*ε', '下界 0', 'Location', 'best');
ylim([-0.05, upper_bound + 0.05]);
fprintf('\n不等式验证 (ε = %.1f):\n', epsilon_test);
fprintf('所有值非负: %s\n', mat2str(all(f_values >= 0)));
fprintf('所有值小于等于上界: %s\n', mat2str(all(f_values <= upper_bound)));
fprintf('最大值: %.6f\n', max(f_values));
fprintf('理论上界: %.6f\n', upper_bound);
%% 第四部分:不同ε值的验证
fprintf('\n不同ε值的验证:\n');
epsilon_values = [0.5, 1, 2, 5];
chi_test = linspace(-20, 20, 2000);
figure('Position', [200, 200, 800, 600]);
colors = ['r', 'b', 'g', 'm'];
for i = 1:length(epsilon_values)
eps = epsilon_values(i);
f_test = abs(chi_test) - chi_test .* tanh(chi_test / eps);
upper_bound_test = 0.2785 * eps;
% 验证
max_f = max(f_test);
is_valid_test = all(f_test >= 0) && all(f_test <= upper_bound_test);
fprintf('ε = %.1f: 最大值 = %.6f, 上界 = %.6f, 有效 = %s\n', ...
eps, max_f, upper_bound_test, mat2str(is_valid_test));
% 绘图
subplot(2,2,i);
plot(chi_test, f_test, colors(i), 'LineWidth', 1.5);
hold on;
plot(chi_test, upper_bound_test * ones(size(chi_test)), 'k--', 'LineWidth', 1);
plot(chi_test, zeros(size(chi_test)), 'k-', 'LineWidth', 0.5);
grid on;
xlabel('χ');
ylabel('|χ| - χtanh(χ/ε)');
title(['ε = ', num2str(eps)]);
legend('f(χ)', '上界', '下界', 'Location', 'best');
ylim([-0.05, upper_bound_test + 0.05]);
end
%% 第五部分:精确求解临界点
fprintf('\n精确数值求解:\n');
% 使用fzero求解g'(t) = 0
t_critical = fzero(g_prime, 1.2); % 初始猜测值1.2
g_max_exact = g(t_critical);
fprintf('精确临界点: t = %.10f\n', t_critical);
fprintf('精确最大值: g(t) = %.10f\n', g_max_exact);
fprintf('与理论值0.2785的差异: %.2e\n', abs(g_max_exact - 0.2785));
代码运行出来的结果为:
运行出来的图看不懂没关系,继续问AI,让它用通俗易懂的语言来解释一下:
第一幅图:基础分析
左图 - 函数g(t) = t(1-tanh(t))这个函数从0开始增长,在t≈1.2处达到最高点0.2785,然后逐渐下降 红色虚线表示最大值μ =
0.2785,这就是引理2中那个神奇常数的来源 可以理解为:当t增大时,tanh(t)越来越接近1,所以(1-tanh(t))越来越小,但t在增大,两者相乘有个最佳平衡点中图 - 导数g’(t)
绿线显示函数的变化率,在红点处穿过零线,说明那里是最高点 这验证了我们找到的最大值点是正确的
右图 - 不等式验证
蓝线是实际的函数值 |χ| - χtanh(χ/ε) 红虚线是理论上界 μ×ε = 0.2785
可以看到蓝线始终在0和红线之间,证明不等式成立
第二幅图:不同ε值的影响
这四个子图展示了ε参数如何影响函数行为:
ε = 0.5(左上,红色)函数变化非常陡峭,几乎像个尖峰 上界很小(约0.14),函数值被严格限制
ε = 1(右上,蓝色)
比ε=0.5稍微平缓一些 上界约0.28
ε = 2(左下,绿色)
函数变得更宽更平缓 上界约0.56
ε = 5(右下,紫色)
函数非常宽广平缓 上界最大(约1.39)
3、关键结论
ε越小:函数变化越陡峭,上界越小,控制越"紧"
ε越大:函数变化越平缓,上界越大,控制越"松"
无论ε多大多小:不等式 0 ≤ |χ| - χtanh(χ/ε) ≤ 0.2785×ε 都成立
这个结果在工程上很有用:
如果你想要系统响应快(陡峭),选小的ε,但控制精度有限
如果你想要系统响应平稳(平缓),选大的ε,但响应会慢一些
不管怎么选,误差都有明确的界限,这让系统设计变得可预测
4、总结:
以上就是关于Claude实现双曲正切函数图像绘制以及双曲正切函数两个性质的证明和代码验证。
接下来的文章我会写关于双曲正切函数在滑模控制中的应用实例分析。