% 基本运算
a = 10; b = 3;
addition = a + b; % 加法:13
subtraction = a - b; % 减法:7
multiplication = a * b; % 乘法:30
division = a / b; % 除法:3.3333
power = a ^ b; % 幂运算:1000
modulo = mod(a, b); % 取模:1
4.1.2 矩阵运算
matlab复制代码
A = [1, 2; 3, 4];
B = [5, 6; 7, 8];
scalar = 2;
% 矩阵加减法
C = A + B; % 矩阵加法:[6 8; 10 12]
D = A - B; % 矩阵减法:[-4 -4; -4 -4]
% 矩阵乘法
E = A * B; % 矩阵乘法:[19 22; 43 50]
F = A * scalar; % 标量乘法:[2 4; 6 8]
% 矩阵除法
G = A / B; % 右除:A * inv(B)
H = A \ B; % 左除:inv(A) * B
% 矩阵幂运算
I = A ^ 2; % 矩阵幂:A * A
4.1.3 逐元素运算(重要!)
matlab复制代码
A = [1, 2; 3, 4];
B = [5, 6; 7, 8];
% 逐元素运算(注意点号)
C = A .* B; % 逐元素乘法:[5 12; 21 32]
D = A ./ B; % 逐元素除法:[0.2 0.333; 0.429 0.5]
E = A .^ 2; % 逐元素平方:[1 4; 9 16]
F = A .^ B; % 逐元素幂运算:[1 64; 2187 65536]
% 逐元素函数
G = sqrt(A); % 逐元素开方
H = sin(A); % 逐元素正弦
I = exp(A); % 逐元素指数
4.2 比较运算符
matlab复制代码
a = 5; b = 3;
A = [1, 2, 3; 4, 5, 6];
B = [1, 0, 4; 4, 5, 0];
% 标量比较
result1 = a > b; % true
result2 = a == b; % false
result3 = a ~= b; % true(注意:不是!=)
result4 = a <= b; % false
% 矩阵比较(逐元素)
C = A > B; % [false true false; false false true]
D = A == B; % [true false false; true true false]
E = A ~= B; % [false true true; false false true]
% 矩阵比较函数
is_equal = isequal(A, B); % false(整体比较)
is_close = all(abs(A-B) < 1e-10, 'all'); % 近似相等判断
4.3 逻辑运算符
matlab复制代码
% 逻辑运算符
a = true; b = false;
result1 = a && b; % 逻辑与(短路):false
result2 = a || b; % 逻辑或(短路):true
result3 = ~a; % 逻辑非:false
% 数组逻辑运算符
A = [true, false; true, true];
B = [false, true; true, false];
C = A & B; % 逐元素与:[false false; true false]
D = A | B; % 逐元素或:[true true; true true]
E = ~A; % 逐元素非:[false true; false false]
% 逻辑函数
result_any = any(A); % 任意元素为真:[true true]
result_all = all(A); % 所有元素为真:[true false]
result_any_all = any(A, 'all'); % 任意元素为真:true
result_all_all = all(A, 'all'); % 所有元素为真:false
% 基本if语句
x = 10;
if x > 5
disp('x大于5');
end
% if-else语句
x = 3;
if x > 5
disp('x大于5');
else
disp('x不大于5');
end
% if-elseif-else语句
score = 85;
if score >= 90
grade = 'A';
elseif score >= 80
grade = 'B';
elseif score >= 70
grade = 'C';
elseif score >= 60
grade = 'D';
else
grade = 'F';
end
fprintf('成绩等级: %s\n', grade);
% 复合条件
age = 25;
income = 50000;
if age >= 18 && income > 30000
disp('符合贷款条件');
elseif age >= 18 || income > 100000
disp('需要进一步评估');
else
disp('不符合贷款条件');
end
5.1.2 switch-case语句
matlab复制代码
% 基本switch语句
day = 3;
switch day
case 1
day_name = '周一';
case 2
day_name = '周二';
case 3
day_name = '周三';
case 4
day_name = '周四';
case 5
day_name = '周五';
case {6, 7} % 多个case值
day_name = '周末';
otherwise
day_name = '无效日期';
end
fprintf('今天是%s\n', day_name);
% 字符串switch
operation = 'add';
a = 10; b = 5;
switch operation
case 'add'
result = a + b;
case 'subtract'
result = a - b;
case 'multiply'
result = a * b;
case 'divide'
if b ~= 0
result = a / b;
else
result = NaN;
end
otherwise
result = NaN;
end
5.2 循环结构
5.2.1 for循环
matlab复制代码
% 基本for循环
for i = 1:5
fprintf('i = %d\n', i);
end
% 步长循环
for i = 1:2:10
fprintf('i = %d\n', i); % 输出1, 3, 5, 7, 9
end
% 递减循环
for i = 10:-1:1
fprintf('i = %d\n', i);
end
% 遍历数组
numbers = [2, 4, 6, 8, 10];
for num = numbers
fprintf('数字: %d\n', num);
end
% 嵌套循环
for i = 1:3
for j = 1:3
fprintf('(%d, %d) ', i, j);
end
fprintf('\n');
end
% 矩阵循环
A = [1, 2, 3; 4, 5, 6];
for i = 1:size(A, 1) % 遍历行
for j = 1:size(A, 2) % 遍历列
fprintf('A(%d,%d) = %d\n', i, j, A(i,j));
end
end
5.2.2 while循环
matlab复制代码
% 基本while循环
i = 1;
while i <= 5
fprintf('i = %d\n', i);
i = i + 1;
end
% 条件循环
sum_val = 0;
i = 1;
while sum_val < 100
sum_val = sum_val + i;
i = i + 1;
end
fprintf('和为%d时,i = %d\n', sum_val, i-1);
% 无限循环(需要break跳出)
counter = 0;
while true
counter = counter + 1;
if counter > 10
break;
end
fprintf('计数器: %d\n', counter);
end
5.2.3 循环控制语句
matlab复制代码
% break语句
for i = 1:10
if i == 5
break; % 跳出循环
end
fprintf('i = %d\n', i);
end
% continue语句
for i = 1:10
if mod(i, 2) == 0
continue; % 跳过偶数
end
fprintf('奇数: %d\n', i);
end
% 嵌套循环中的break
for i = 1:3
for j = 1:3
if i == 2 && j == 2
break; % 只跳出内层循环
end
fprintf('(%d, %d) ', i, j);
end
fprintf('\n');
end
5.3 异常处理
matlab复制代码
% try-catch语句
try
a = 10;
b = 0;
result = a / b; % 这会产生Inf,不是错误
% 故意产生错误
matrix = [1, 2; 3, 4];
value = matrix(5, 5); % 索引越界
catch ME
fprintf('捕获到错误: %s\n', ME.message);
fprintf('错误标识符: %s\n', ME.identifier);
fprintf('错误位置: %s, 行%d\n', ME.stack(1).name, ME.stack(1).line);
% 处理错误
result = NaN;
end
% 完整的try-catch-end结构
filename = 'nonexistent.txt';
try
data = load(filename);
fprintf('文件加载成功\n');
catch ME
if strcmp(ME.identifier, 'MATLAB:load:couldNotReadFile')
fprintf('文件不存在: %s\n', filename);
data = [];
else
fprintf('未知错误: %s\n', ME.message);
rethrow(ME); % 重新抛出错误
end
end
6. 函数编程
6.1 函数基础
6.1.1 函数定义
matlab复制代码
% 基本函数定义(保存为separate .m文件)
function result = square(x)
% SQUARE 计算输入的平方
% 输入: x - 数值或数组
% 输出: result - x的平方
result = x .^ 2;
end
% 多输入参数函数
function result = add_numbers(a, b, c)
% 计算三个数的和
result = a + b + c;
end
% 多输出参数函数
function [sum_val, diff_val, prod_val] = calculate(a, b)
% 计算两数的和、差、积
sum_val = a + b;
diff_val = a - b;
prod_val = a * b;
end
% 可变参数函数
function result = sum_all(varargin)
% 计算所有输入参数的和
result = 0;
for i = 1:nargin
result = result + varargin{i};
end
end
6.1.2 函数调用
matlab复制代码
% 调用基本函数
x = 5;
y = square(x); % y = 25
% 调用多参数函数
result = add_numbers(1, 2, 3); % result = 6
% 调用多输出函数
[s, d, p] = calculate(10, 5); % s=15, d=5, p=50
s_only = calculate(10, 5); % 只获取第一个输出
% 调用可变参数函数
total = sum_all(1, 2, 3, 4, 5); % total = 15
6.2 高级函数特性
6.2.1 默认参数和参数检查
matlab复制代码
% 使用inputParser进行参数解析
function result = advanced_function(data, varargin)
% 高级函数示例,演示参数解析
% 创建输入解析器
p = inputParser;
% 必需参数
addRequired(p, 'data', @isnumeric);
% 可选参数
addOptional(p, 'method', 'mean', @(x) any(validatestring(x, {'mean', 'median', 'sum'})));
% 名称-值对参数
addParameter(p, 'normalize', false, @islogical);
addParameter(p, 'precision', 2, @(x) isnumeric(x) && x > 0);
% 解析输入
parse(p, data, varargin{:});
% 提取参数
method = p.Results.method;
normalize = p.Results.normalize;
precision = p.Results.precision;
% 数据预处理
if normalize
data = data / max(data);
end
% 根据方法计算结果
switch method
case 'mean'
result = mean(data);
case 'median'
result = median(data);
case 'sum'
result = sum(data);
end
% 精度控制
result = round(result, precision);
end
% 调用示例
data = [1, 2, 3, 4, 5];
result1 = advanced_function(data); % 使用默认参数
result2 = advanced_function(data, 'median'); % 指定方法
result3 = advanced_function(data, 'sum', 'normalize', true); % 使用名称-值对
6.2.2 嵌套函数和子函数
matlab复制代码
% 嵌套函数示例
function main_function()
% 主函数
x = 10;
y = 5;
% 调用嵌套函数
result = nested_calculation();
fprintf('结果: %d\n', result);
% 嵌套函数可以访问主函数的变量
function output = nested_calculation()
output = x + y; % 可以直接使用x和y
end
end
% 子函数示例(在同一个.m文件中)
function main_with_subfunctions()
% 主函数
data = [1, 2, 3, 4, 5];
processed = process_data(data);
display_results(processed);
end
function result = process_data(data)
% 子函数1
result = data .* 2 + 1;
end
function display_results(data)
% 子函数2
fprintf('处理后的数据: ');
fprintf('%d ', data);
fprintf('\n');
end
6.2.3 匿名函数和函数句柄
matlab复制代码
% 匿名函数
square_func = @(x) x.^2;
result = square_func(5); % 25
% 多参数匿名函数
add_func = @(a, b) a + b;
result = add_func(3, 4); % 7
% 复杂匿名函数
complex_func = @(x, y) sqrt(x.^2 + y.^2);
result = complex_func(3, 4); % 5
% 函数句柄
my_sin = @sin;
result = my_sin(pi/2); % 1
% 传递函数作为参数
function result = apply_function(data, func)
result = func(data);
end
data = [1, 2, 3, 4, 5];
squared = apply_function(data, @(x) x.^2);
6.2.4 递归函数
matlab复制代码
% 阶乘函数
function result = factorial_recursive(n)
if n <= 1
result = 1;
else
result = n * factorial_recursive(n - 1);
end
end
% 斐波那契数列
function result = fibonacci(n)
if n <= 1
result = n;
else
result = fibonacci(n-1) + fibonacci(n-2);
end
end
% 优化的斐波那契(使用持久变量)
function result = fibonacci_optimized(n)
persistent cache;
if isempty(cache)
cache = containers.Map('KeyType', 'int32', 'ValueType', 'double');
end
if n <= 1
result = n;
elseif isKey(cache, n)
result = cache(n);
else
result = fibonacci_optimized(n-1) + fibonacci_optimized(n-2);
cache(n) = result;
end
end
% 断点调试
function debug_example()
x = 1:10;
y = x.^2;
% 在此处设置断点
keyboard; % 手动断点
z = y + x;
result = sum(z);
fprintf('结果: %d\n', result);
end
% 条件断点
function conditional_debug()
for i = 1:100
value = rand();
if value > 0.95
keyboard; % 当条件满足时暂停
end
end
end
12.2 错误处理策略
matlab复制代码
% 完整的错误处理示例
function safe_divide(a, b)
try
% 参数验证
if nargin < 2
error('需要两个输入参数');
end
if ~isnumeric(a) || ~isnumeric(b)
error('输入必须是数值');
end
if b == 0
warning('除数为零,返回Inf');
result = Inf;
else
result = a / b;
end
fprintf('结果: %.4f\n', result);
catch ME
% 错误处理
fprintf('错误类型: %s\n', ME.identifier);
fprintf('错误信息: %s\n', ME.message);
% 记录错误
log_error(ME);
% 重新抛出特定错误
if strcmp(ME.identifier, 'MATLAB:narginchk:notEnoughInputs')
rethrow(ME);
end
end
end
function log_error(error_info)
% 错误日志记录
log_file = 'error_log.txt';
fid = fopen(log_file, 'a');
fprintf(fid, '[%s] %s: %s\n', datestr(now), error_info.identifier, error_info.message);
fclose(fid);
end
13. 性能优化
13.1 向量化操作
matlab复制代码
% 避免循环,使用向量化
% 低效的循环方式
tic;
n = 1000000;
result_loop = zeros(n, 1);
for i = 1:n
result_loop(i) = sin(i) + cos(i);
end
time_loop = toc;
% 高效的向量化方式
tic;
x = 1:n;
result_vectorized = sin(x) + cos(x);
time_vectorized = toc;
fprintf('循环时间: %.4f秒\n', time_loop);
fprintf('向量化时间: %.4f秒\n', time_vectorized);
fprintf('速度提升: %.2f倍\n', time_loop / time_vectorized);
13.2 内存管理
matlab复制代码
% 预分配数组
% 低效方式
tic;
slow_array = [];
for i = 1:10000
slow_array(end+1) = i^2;
end
time_slow = toc;
% 高效方式
tic;
fast_array = zeros(10000, 1);
for i = 1:10000
fast_array(i) = i^2;
end
time_fast = toc;
fprintf('动态分配时间: %.4f秒\n', time_slow);
fprintf('预分配时间: %.4f秒\n', time_fast);
13.3 性能分析
matlab复制代码
% 使用profile进行性能分析
profile on;
complex_calculation();
profile off;
profile viewer; % 查看性能报告
function complex_calculation()
% 复杂计算示例
data = randn(1000, 1000);
% 矩阵运算
result1 = data * data';
% 统计计算
result2 = mean(data, 2);
% 排序
result3 = sort(data, 2);
end
% 项目:求解偏微分方程(热传导方程)
% 参数设置
L = 1; % 长度
T = 0.1; % 时间
alpha = 0.01; % 热扩散系数
nx = 50; % 空间网格数
nt = 1000; % 时间步数
% 网格
dx = L / (nx - 1);
dt = T / nt;
x = 0:dx:L;
t = 0:dt:T;
% 稳定性检查
r = alpha * dt / dx^2;
if r > 0.5
warning('数值不稳定,r = %.3f > 0.5', r);
end
% 初始条件
u = zeros(nx, nt+1);
u(:, 1) = sin(pi * x); % 初始温度分布
% 边界条件(两端为0)
u(1, :) = 0;
u(end, :) = 0;
% 有限差分求解
for n = 1:nt
for i = 2:nx-1
u(i, n+1) = u(i, n) + r * (u(i+1, n) - 2*u(i, n) + u(i-1, n));
end
end
% 解析解(用于验证)
u_analytical = zeros(nx, length(t));
for i = 1:length(t)
u_analytical(:, i) = exp(-pi^2 * alpha * t(i)) * sin(pi * x);
end
% 绘制结果
figure('Position', [100, 100, 1200, 800]);
% 3D图
subplot(2,2,1);
[T_mesh, X_mesh] = meshgrid(t, x);
surf(T_mesh, X_mesh, u);
title('热传导方程数值解');
xlabel('时间');
ylabel('位置');
zlabel('温度');
% 不同时间点的温度分布
subplot(2,2,2);
time_points = [1, 101, 301, 501, 1001];
colors = ['b', 'r', 'g', 'm', 'k'];
for i = 1:length(time_points)
plot(x, u(:, time_points(i)), colors(i), 'LineWidth', 2);
hold on;
end
title('不同时间点的温度分布');
xlabel('位置');
ylabel('温度');
legend('t=0', 't=0.01', 't=0.03', 't=0.05', 't=0.1');
% 数值解vs解析解
subplot(2,2,3);
final_time_idx = length(t);
plot(x, u(:, final_time_idx), 'b-', 'LineWidth', 2);
hold on;
plot(x, u_analytical(:, final_time_idx), 'r--', 'LineWidth', 2);
title('t=0.1时的数值解与解析解比较');
xlabel('位置');
ylabel('温度');
legend('数值解', '解析解');
% 误差分析
subplot(2,2,4);
error = abs(u(:, final_time_idx) - u_analytical(:, final_time_idx));
plot(x, error, 'r-', 'LineWidth', 2);
title('数值解误差');
xlabel('位置');
ylabel('绝对误差');
fprintf('=== 数值计算报告 ===\n');
fprintf('网格数: %d\n', nx);
fprintf('时间步数: %d\n', nt);
fprintf('稳定性参数 r: %.3f\n', r);
fprintf('最大误差: %.6f\n', max(error));
fprintf('平均误差: %.6f\n', mean(error));
16. 常见问题与解决方案
16.1 常见错误及解决方法
16.1.1 索引错误
matlab复制代码
% 错误示例
A = [1, 2, 3];
try
value = A(0); % MATLAB索引从1开始,不是0
catch ME
fprintf('错误: %s\n', ME.message);
end
% 正确方法
value = A(1); % 获取第一个元素
% 动态索引检查
function safe_index = get_safe_index(array, index)
if index < 1 || index > length(array)
error('索引超出范围');
end
safe_index = array(index);
end
16.1.2 维度不匹配
matlab复制代码
% 错误示例
A = [1, 2, 3]; % 1×3
B = [4; 5; 6]; % 3×1
try
C = A + B;
catch ME
fprintf('错误: %s\n', ME.message);
end
% 解决方法1:转置
C1 = A + B'; % 1×3 + 1×3
% 解决方法2:使用广播
C2 = A + B'; % 自动广播
% 解决方法3:显式重塑
C3 = A + reshape(B, 1, 3);
16.1.3 数据类型问题
matlab复制代码
% 整数溢出
a = uint8(255);
b = uint8(10);
c = a + b; % 溢出,结果为255而不是265
fprintf('uint8溢出: %d + %d = %d\n', a, b, c);
% 解决方法:使用更大的数据类型
a_double = double(a);
b_double = double(b);
c_correct = a_double + b_double;
fprintf('正确结果: %.0f + %.0f = %.0f\n', a_double, b_double, c_correct);
% 性能测试函数
function performance_comparison()
n = 1000;
% 方法1:循环
tic;
result1 = zeros(n, 1);
for i = 1:n
result1(i) = sin(i) * cos(i);
end
time1 = toc;
% 方法2:向量化
tic;
x = (1:n)';
result2 = sin(x) .* cos(x);
time2 = toc;
% 方法3:内置函数
tic;
x = (1:n)';
result3 = 0.5 * sin(2*x); % 使用三角恒等式
time3 = toc;
fprintf('循环方法: %.6f 秒\n', time1);
fprintf('向量化方法: %.6f 秒\n', time2);
fprintf('优化方法: %.6f 秒\n', time3);
% 验证结果一致性
fprintf('结果一致性: %s\n', ...
isequal(round(result1, 10), round(result2, 10), round(result3, 10)));
end
performance_comparison();
16.3 调试技巧
16.3.1 断点和单步执行
matlab复制代码
% 调试示例函数
function result = debug_example(x)
% 设置断点:在此行左边点击
y = x.^2;
% 条件断点
if any(y > 100)
disp('发现大值'); % 在此设置断点
end
% 变量检查
z = sin(y);
result = sum(z);
end
% 调试命令
% dbstop in debug_example at 3 % 在第3行设置断点
% dbclear all % 清除所有断点
% dbstack % 显示调用栈
16.3.2 异常处理
matlab复制代码
% 健壮的异常处理
function robust_calculation(data)
try
% 输入验证
if ~isnumeric(data)
error('输入必须是数值');
end
if any(isnan(data))
warning('数据包含NaN值,将被忽略');
data = data(~isnan(data));
end
% 主要计算
result = sqrt(mean(data.^2));
fprintf('RMS值: %.4f\n', result);
catch ME
fprintf('错误发生在: %s\n', ME.stack(1).name);
fprintf('错误行号: %d\n', ME.stack(1).line);
fprintf('错误信息: %s\n', ME.message);
% 记录错误
error_log = struct('time', datetime, 'error', ME.message, 'data_size', size(data));
save('error_log.mat', 'error_log', '-append');
end
end
% 测试异常处理
robust_calculation([1, 2, 3, NaN, 5]);
robust_calculation('invalid');
% 良好的代码组织示例
function result = data_analysis_pipeline(data_file)
% DATA_ANALYSIS_PIPELINE 数据分析流水线
%
% 输入:
% data_file - 数据文件路径
% 输出:
% result - 分析结果结构体
% 验证输入
validateInputs(data_file);
% 数据加载和预处理
data = loadData(data_file);
cleaned_data = preprocessData(data);
% 分析
stats = calculateStatistics(cleaned_data);
model = fitModel(cleaned_data);
% 可视化
figures = createVisualizations(cleaned_data, model);
% 组织结果
result = struct('statistics', stats, 'model', model, 'figures', figures);
% 生成报告
generateReport(result);
end
function validateInputs(data_file)
% 输入验证
if ~ischar(data_file) && ~isstring(data_file)
error('数据文件路径必须是字符串');
end
if ~exist(data_file, 'file')
error('文件不存在: %s', data_file);
end
end
function data = loadData(data_file)
% 数据加载逻辑
[~, ~, ext] = fileparts(data_file);
switch lower(ext)
case '.csv'
data = readtable(data_file);
case '.xlsx'
data = readtable(data_file);
case '.mat'
loaded = load(data_file);
data = loaded.data;
otherwise
error('不支持的文件格式: %s', ext);
end
end
16.9.2 性能优化技巧
matlab复制代码
% 性能优化示例
function optimized_computation()
% 坏的做法:动态增长数组
tic;
result_bad = [];
for i = 1:10000
result_bad = [result_bad, i^2]; % 每次重新分配内存
end
time_bad = toc;
% 好的做法:预分配数组
tic;
result_good = zeros(1, 10000); % 预分配
for i = 1:10000
result_good(i) = i^2;
end
time_good = toc;
% 最好的做法:向量化
tic;
result_best = (1:10000).^2; % 向量化运算
time_best = toc;
fprintf('动态增长: %.4f 秒\n', time_bad);
fprintf('预分配: %.4f 秒\n', time_good);
fprintf('向量化: %.4f 秒\n', time_best);
end
% 内存效率优化
function memory_efficient_processing()
% 处理大数据时的内存管理
% 使用单精度而非双精度(当精度允许时)
data_double = rand(1000, 1000); % 8 MB
data_single = single(rand(1000, 1000)); % 4 MB
% 及时清理不需要的变量
large_array = rand(10000, 10000);
processed = process_data(large_array);
clear large_array; % 释放内存
% 分块处理大数据
chunk_size = 1000;
total_size = 100000;
result = zeros(total_size, 1);
for i = 1:chunk_size:total_size
end_idx = min(i + chunk_size - 1, total_size);
chunk = generate_data_chunk(i, end_idx);
result(i:end_idx) = process_chunk(chunk);
clear chunk; % 清理临时数据
end
end
16.9.3 调试技巧
matlab复制代码
% 调试工具和技巧
function debugging_example()
% 使用断点和调试器
data = [1, 2, 3, NaN, 5, 6];
% 检查数据质量
if any(isnan(data))
warning('数据包含NaN值');
fprintf('NaN位置: %s\n', mat2str(find(isnan(data))));
end
% 使用try-catch处理错误
try
result = risky_computation(data);
catch ME
fprintf('错误发生在: %s\n', ME.stack(1).name);
fprintf('错误信息: %s\n', ME.message);
result = handle_error(data);
end
% 添加详细日志
log_computation_steps(data, result);
end
function result = risky_computation(data)
% 可能出错的计算
if any(data < 0)
error('输入数据不能包含负值');
end
result = sqrt(data);
end
function result = handle_error(data)
% 错误处理逻辑
data = abs(data); % 取绝对值
data(isnan(data)) = 0; % 替换NaN
result = sqrt(data);
end
function log_computation_steps(input_data, output_data)
% 记录计算步骤
fprintf('=== 计算日志 ===\n');
fprintf('输入数据大小: %s\n', mat2str(size(input_data)));
fprintf('输入数据范围: [%.2f, %.2f]\n', min(input_data), max(input_data));
fprintf('输出数据大小: %s\n', mat2str(size(output_data)));
fprintf('输出数据范围: [%.2f, %.2f]\n', min(output_data), max(output_data));
fprintf('计算完成时间: %s\n', datestr(now));
end
16.10 常见错误及解决方案
16.10.1 索引错误
matlab复制代码
% 常见索引错误及解决方案
function index_error_solutions()
A = rand(5, 5);
% 错误1:超出数组边界
try
value = A(6, 3); % 错误:超出边界
catch
fprintf('错误:数组索引超出边界\n');
% 解决方案:检查边界
[rows, cols] = size(A);
row_idx = min(6, rows);
col_idx = min(3, cols);
value = A(row_idx, col_idx);
end
% 错误2:使用0作为索引
try
value = A(0, 1); % 错误:MATLAB索引从1开始
catch
fprintf('错误:MATLAB索引从1开始,不是0\n');
% 解决方案
value = A(1, 1); % 正确
end
% 错误3:维度不匹配
B = rand(3, 4);
try
C = A + B; % 错误:维度不匹配
catch
fprintf('错误:矩阵维度不匹配\n');
% 解决方案:调整维度或使用兼容操作
if isequal(size(A), size(B))
C = A + B;
else
fprintf('无法直接相加,维度分别为 %s 和 %s\n', ...
mat2str(size(A)), mat2str(size(B)));
end
end
end
16.10.2 数据类型错误
matlab复制代码
% 数据类型相关错误
function data_type_solutions()
% 错误1:字符串和数值混合
data = {'apple', 'banana', 3, 'cherry'};
% 尝试对混合数据进行数值运算
numeric_data = [];
string_data = {};
for i = 1:length(data)
if isnumeric(data{i})
numeric_data = [numeric_data, data{i}];
else
string_data{end+1} = data{i};
end
end
fprintf('数值数据: %s\n', mat2str(numeric_data));
fprintf('字符串数据: %s\n', strjoin(string_data, ', '));
% 错误2:精度损失
x = 0.1 + 0.2;
if x == 0.3
fprintf('相等\n');
else
fprintf('不相等,x = %.17f\n', x);
% 解决方案:使用容差比较
tolerance = 1e-10;
if abs(x - 0.3) < tolerance
fprintf('在容差范围内相等\n');
end
end
end
16.11 项目实战综合案例
16.11.1 股票数据分析系统
matlab复制代码
% 股票数据分析系统
classdef StockAnalyzer < handle
properties
data
symbols
dates
prices
end
methods
function obj = StockAnalyzer()
obj.data = containers.Map();
end
function loadData(obj, filename)
% 加载股票数据
if exist(filename, 'file')
raw_data = readtable(filename);
obj.symbols = unique(raw_data.Symbol);
obj.dates = unique(raw_data.Date);
for i = 1:length(obj.symbols)
symbol = obj.symbols{i};
symbol_data = raw_data(strcmp(raw_data.Symbol, symbol), :);
obj.data(symbol) = symbol_data;
end
fprintf('成功加载 %d 只股票的数据\n', length(obj.symbols));
else
error('文件不存在: %s', filename);
end
end
function returns = calculateReturns(obj, symbol, period)
% 计算收益率
if ~obj.data.isKey(symbol)
error('未找到股票代码: %s', symbol);
end
stock_data = obj.data(symbol);
prices = stock_data.Close;
switch lower(period)
case 'daily'
returns = diff(log(prices));
case 'weekly'
returns = diff(log(prices(1:5:end)));
case 'monthly'
returns = diff(log(prices(1:22:end)));
otherwise
error('不支持的周期: %s', period);
end
end
function stats = analyzeVolatility(obj, symbol, window)
% 分析波动率
returns = obj.calculateReturns(symbol, 'daily');
% 滚动波动率
rolling_vol = zeros(length(returns) - window + 1, 1);
for i = 1:length(rolling_vol)
rolling_vol(i) = std(returns(i:i+window-1));
end
stats = struct();
stats.mean_volatility = mean(rolling_vol);
stats.max_volatility = max(rolling_vol);
stats.min_volatility = min(rolling_vol);
stats.rolling_volatility = rolling_vol;
end
function visualizeAnalysis(obj, symbol)
% 可视化分析结果
if ~obj.data.isKey(symbol)
error('未找到股票代码: %s', symbol);
end
stock_data = obj.data(symbol);
figure('Position', [100, 100, 1200, 800]);
% 价格走势
subplot(3, 1, 1);
plot(stock_data.Date, stock_data.Close, 'b-', 'LineWidth', 1.5);
title(sprintf('%s 股价走势', symbol));
ylabel('价格');
grid on;
% 成交量
subplot(3, 1, 2);
bar(stock_data.Date, stock_data.Volume, 'FaceColor', [0.7, 0.7, 0.7]);
title(sprintf('%s 成交量', symbol));
ylabel('成交量');
grid on;
% 收益率分布
subplot(3, 1, 3);
returns = obj.calculateReturns(symbol, 'daily');
histogram(returns, 50, 'FaceColor', [0.2, 0.6, 0.8]);
title(sprintf('%s 日收益率分布', symbol));
xlabel('收益率');
ylabel('频次');
grid on;
% 添加统计信息
mu = mean(returns);
sigma = std(returns);
text(0.7, 0.8, sprintf('均值: %.4f\n标准差: %.4f\n夏普比率: %.2f', ...
mu, sigma, mu/sigma*sqrt(252)), 'Units', 'normalized', ...
'BackgroundColor', 'white', 'EdgeColor', 'black');
end
function correlation_matrix = calculateCorrelation(obj, symbols)
% 计算股票间相关性
if nargin < 2
symbols = obj.symbols(1:min(10, length(obj.symbols)));
end
returns_matrix = [];
valid_symbols = {};
for i = 1:length(symbols)
if obj.data.isKey(symbols{i})
returns = obj.calculateReturns(symbols{i}, 'daily');
returns_matrix = [returns_matrix, returns];
valid_symbols{end+1} = symbols{i};
end
end
correlation_matrix = corrcoef(returns_matrix);
% 可视化相关性矩阵
figure;
imagesc(correlation_matrix);
colorbar;
colormap('cool');
set(gca, 'XTick', 1:length(valid_symbols), 'XTickLabel', valid_symbols);
set(gca, 'YTick', 1:length(valid_symbols), 'YTickLabel', valid_symbols);
title('股票收益率相关性矩阵');
% 添加数值标签
for i = 1:size(correlation_matrix, 1)
for j = 1:size(correlation_matrix, 2)
text(j, i, sprintf('%.2f', correlation_matrix(i,j)), ...
'HorizontalAlignment', 'center', 'Color', 'white');
end
end
end
end
end
% 使用示例
function stock_analysis_demo()
% 创建分析器实例
analyzer = StockAnalyzer();
% 生成示例数据(实际使用中应该加载真实数据)
generate_sample_data();
% 加载数据
analyzer.loadData('sample_stock_data.csv');
% 分析特定股票
symbol = 'AAPL';
% 计算收益率
returns = analyzer.calculateReturns(symbol, 'daily');
fprintf('%s 平均日收益率: %.4f%%\n', symbol, mean(returns)*100);
% 分析波动率
vol_stats = analyzer.analyzeVolatility(symbol, 30);
fprintf('%s 平均30日波动率: %.4f\n', symbol, vol_stats.mean_volatility);
% 可视化分析
analyzer.visualizeAnalysis(symbol);
% 计算相关性
symbols = {'AAPL', 'GOOGL', 'MSFT', 'TSLA'};
corr_matrix = analyzer.calculateCorrelation(symbols);
fprintf('相关性分析完成\n');
end
function generate_sample_data()
% 生成示例股票数据
symbols = {'AAPL', 'GOOGL', 'MSFT', 'TSLA', 'AMZN'};
dates = datetime('2020-01-01'):caldays(1):datetime('2023-12-31');
dates = dates(~isweekend(dates)); % 排除周末
all_data = table();
for i = 1:length(symbols)
symbol = symbols{i};
n_days = length(dates);
% 生成模拟价格数据(几何布朗运动)
S0 = 100 + randn * 20; % 初始价格
mu = 0.08 / 252; % 年化收益率转日收益率
sigma = 0.2 / sqrt(252); % 年化波动率转日波动率
returns = normrnd(mu, sigma, n_days-1, 1);
log_prices = cumsum([log(S0); returns]);
prices = exp(log_prices);
% 生成成交量数据
base_volume = 1e6 + randn * 2e5;
volumes = abs(base_volume + randn(n_days, 1) * 1e5);
% 创建数据表
symbol_data = table();
symbol_data.Symbol = repmat({symbol}, n_days, 1);
symbol_data.Date = dates';
symbol_data.Close = prices;
symbol_data.Volume = volumes;
all_data = [all_data; symbol_data];
end
% 保存数据
writetable(all_data, 'sample_stock_data.csv');
fprintf('示例数据已生成并保存到 sample_stock_data.csv\n');
end