1. MATLAB简介与环境
跳转到“1. MATLAB简介与环境”1.1 什么是MATLAB
跳转到“1.1 什么是MATLAB”MATLAB(Matrix Laboratory)是一个高性能的数值计算环境和编程语言,专为工程计算、数据分析和算法开发设计。
1.2 与Python/C++的对比
跳转到“1.2 与Python/C++的对比”| 特性 | Python | C/C++ | MATLAB |
|---|---|---|---|
| 类型 | 解释型 | 编译型 | 解释型 |
| 主要用途 | 通用编程 | 系统编程 | 数值计算 |
| 矩阵运算 | 需要NumPy | 需要库 | 内置支持 |
| 学习曲线 | 平缓 | 陡峭 | 中等 |
| 执行速度 | 中等 | 最快 | 快(矩阵运算) |
1.3 MATLAB环境
跳转到“1.3 MATLAB环境”- 命令窗口(Command Window): 交互式执行命令
- 编辑器(Editor): 编写和编辑脚本、函数
- 工作区(Workspace): 查看变量
- 命令历史(Command History): 查看历史命令
- 当前文件夹(Current Folder): 文件管理
1.4 基本操作命令
跳转到“1.4 基本操作命令”% 基本环境命令clc % 清除命令窗口clear % 清除工作区所有变量clear var % 清除指定变量close all % 关闭所有图形窗口who % 显示当前变量列表whos % 详细显示变量信息pwd % 显示当前路径cd % 改变当前路径ls % 列出当前目录文件2. 基本语法与数据类型
跳转到“2. 基本语法与数据类型”2.1 语法规则
跳转到“2.1 语法规则”% 注释:单行注释用%,多行注释用%{ %}% 这是单行注释
%{这是多行注释可以写很多行%}
% 语句结束:a = 5; % 分号抑制输出b = 3 % 不加分号会显示结果
% 续行:使用...long_variable_name = 1 + 2 + 3 + ... 4 + 5 + 6;2.2 变量命名规则
跳转到“2.2 变量命名规则”% 命名规则:% 1. 以字母开头% 2. 只能包含字母、数字、下划线% 3. 区分大小写% 4. 不能使用关键字
% 有效的变量名var1 = 10;my_variable = 20;MyVariable = 30;variable_2023 = 40;
% 无效的变量名(会报错)% 2var = 10; % 以数字开头% my-var = 20; % 包含连字符% for = 30; % 使用关键字2.3 数据类型详解
跳转到“2.3 数据类型详解”2.3.1 数值类型
跳转到“2.3.1 数值类型”% 双精度浮点数(默认)a = 3.14159;b = 1.23e-4; % 科学记数法c = 1.23e4;
% 整数类型int8_var = int8(127); % 8位有符号整数uint8_var = uint8(255); % 8位无符号整数int16_var = int16(32767); % 16位有符号整数uint16_var = uint16(65535); % 16位无符号整数int32_var = int32(2147483647); % 32位有符号整数uint32_var = uint32(4294967295); % 32位无符号整数int64_var = int64(9223372036854775807); % 64位有符号整数
% 单精度浮点数single_var = single(3.14159);
% 复数complex_var = 3 + 4i; % 或 3 + 4*icomplex_var2 = complex(3, 4);2.3.2 逻辑类型
跳转到“2.3.2 逻辑类型”% 布尔值bool_true = true;bool_false = false;
% 逻辑运算结果result = (5 > 3); % trueresult2 = (2 == 3); % false
% 逻辑数组logical_array = [true, false, true];2.3.3 字符和字符串
跳转到“2.3.3 字符和字符串”% 字符数组(传统方式)char_var = 'Hello';char_array = ['Hello'; 'World']; % 注意:每行长度必须相同
% 字符串数组(R2016b及以后)str_var = "Hello";str_array = ["Hello", "World", "MATLAB"];
% 字符串与字符数组的区别char_example = 'Hello'; % 1x5 charstring_example = "Hello"; % 1x1 string2.4 类型转换
跳转到“2.4 类型转换”% 数值转换a = 3.14;b = int32(a); % 转换为32位整数c = single(a); % 转换为单精度d = char(65); % ASCII转字符: 'A'
% 字符串转换num_str = '123';num_val = str2double(num_str); % 字符串转数值num_val2 = str2num(num_str); % 字符串转数值(可处理向量)
% 数值转字符串val = 3.14159;str_val = num2str(val); % 数值转字符串str_val2 = sprintf('%.2f', val); % 格式化转换3. 数组和矩阵操作
跳转到“3. 数组和矩阵操作”3.1 数组创建
跳转到“3.1 数组创建”3.1.1 直接创建
跳转到“3.1.1 直接创建”% 行向量row_vector = [1, 2, 3, 4, 5];row_vector2 = [1 2 3 4 5]; % 逗号可省略
% 列向量col_vector = [1; 2; 3; 4; 5];
% 矩阵matrix = [1, 2, 3; 4, 5, 6; 7, 8, 9];matrix2 = [1 2 3 4 5 6 7 8 9]; % 分行写法3.1.2 使用函数创建
跳转到“3.1.2 使用函数创建”% 特殊矩阵zeros_matrix = zeros(3, 4); % 3x4零矩阵ones_matrix = ones(2, 5); % 2x5全1矩阵eye_matrix = eye(4); % 4x4单位矩阵diag_matrix = diag([1,2,3,4]); % 对角矩阵
% 随机矩阵rand_matrix = rand(3, 3); % 3x3均匀分布随机矩阵[0,1]randn_matrix = randn(2, 4); % 2x4标准正态分布随机矩阵randi_matrix = randi(10, 3, 3); % 3x3随机整数矩阵[1,10]randi_matrix2 = randi([5,15], 2, 3); % 2x3随机整数矩阵[5,15]3.1.3 序列创建
跳转到“3.1.3 序列创建”% 等差数列seq1 = 1:5; % [1 2 3 4 5]seq2 = 1:2:10; % [1 3 5 7 9],步长为2seq3 = 10:-1:1; % [10 9 8 7 6 5 4 3 2 1],递减
% 等间距数列linspace_seq = linspace(0, 10, 5); % 0到10等分5个点logspace_seq = logspace(1, 3, 5); % 10^1到10^3等分5个点(对数空间)
% 重复数组repmat_array = repmat([1, 2], 3, 2); % 重复[1,2] 3行2列3.2 数组索引与切片
跳转到“3.2 数组索引与切片”3.2.1 基本索引(注意:MATLAB索引从1开始!)
跳转到“3.2.1 基本索引(注意:MATLAB索引从1开始!)”A = [1, 2, 3; 4, 5, 6; 7, 8, 9];
% 单个元素element = A(2, 3); % 第2行第3列:6element2 = A(1, 1); % 第1行第1列:1
% 线性索引(按列优先)linear_element = A(5); % 第5个元素:5linear_element2 = A(end); % 最后一个元素:9
% 使用end关键字last_element = A(end, end); % 最后一行最后一列:9second_last = A(end-1, end); % 倒数第二行最后一列:63.2.2 切片操作
跳转到“3.2.2 切片操作”A = [1, 2, 3, 4; 5, 6, 7, 8; 9, 10, 11, 12];
% 行切片first_row = A(1, :); % 第1行所有列:[1 2 3 4]last_row = A(end, :); % 最后一行:[9 10 11 12]
% 列切片first_col = A(:, 1); % 所有行第1列:[1; 5; 9]last_col = A(:, end); % 最后一列:[4; 8; 12]
% 子矩阵sub_matrix = A(1:2, 2:3); % 第1-2行,第2-3列:[2 3; 6 7]sub_matrix2 = A([1,3], [2,4]); % 第1,3行,第2,4列:[2 4; 10 12]
% 所有元素all_elements = A(:); % 所有元素(列向量)| 特性 | MATLAB | NumPy (Python) |
|---|---|---|
| 索引起始 | 从1开始 | 从0开始 |
| 语法 | 圆括号 A(行, 列) | 方括号 A[行, 列] |
| 第一个元素 | A(1, 1) | A[0, 0] |
| 范围索引 | A(1:3, 1:2) | A[0:3, 0:2] |
| 间隔索引 | A([1:3], [1:2]) | A[[0:3], [0:2]] |
| 逆向 | end:-1:1 | ::-1 |
| 所有行/列 | A(:, 2) | A[:, 1] |
| 最后一个元素 | A(end, end) | A[-1, -1] |
3.2.3 逻辑索引
跳转到“3.2.3 逻辑索引”A = [1, -2, 3; -4, 5, -6; 7, -8, 9];
% 逻辑条件positive_mask = A > 0; % 逻辑矩阵positive_elements = A(A > 0); % 提取正数:[1; 3; 5; 7; 9]
% 复合条件condition = (A > 0) & (A < 8); % 大于0且小于8selected = A(condition); % [1; 3; 5; 7]
% 替换元素A(A < 0) = 0; % 将负数替换为03.3 数组操作
跳转到“3.3 数组操作”3.3.1 数组拼接
跳转到“3.3.1 数组拼接”% 水平拼接A = [1, 2; 3, 4];B = [5, 6; 7, 8];C_horizontal = [A, B]; % [1 2 5 6; 3 4 7 8]C_horizontal2 = horzcat(A, B); % 同上
% 垂直拼接C_vertical = [A; B]; % [1 2; 3 4; 5 6; 7 8]C_vertical2 = vertcat(A, B); % 同上
% 高维拼接C_3d = cat(3, A, B); % 沿第3维拼接3.3.2 数组重塑
跳转到“3.3.2 数组重塑”A = [1, 2, 3, 4, 5, 6];
% 重塑形状B = reshape(A, 2, 3); % 重塑为2x3:[1 3 5; 2 4 6]C = reshape(A, 3, 2); % 重塑为3x2:[1 4; 2 5; 3 6]
% 转置A_matrix = [1, 2, 3; 4, 5, 6];A_transpose = A_matrix'; % 转置:[1 4; 2 5; 3 6]A_transpose2 = transpose(A_matrix); % 同上
% 复数矩阵的共轭转置complex_matrix = [1+2i, 3-4i; 5+6i, 7-8i];conjugate_transpose = complex_matrix'; % 共轭转置transpose_only = complex_matrix.'; % 仅转置(不共轭)3.3.3 数组排序
跳转到“3.3.3 数组排序”% 向量排序vec = [3, 1, 4, 1, 5, 9];sorted_vec = sort(vec); % 升序:[1 1 3 4 5 9]sorted_desc = sort(vec, 'descend'); % 降序:[9 5 4 3 1 1]
% 获取排序索引[sorted_vec, indices] = sort(vec);% sorted_vec = [1 1 3 4 5 9]% indices = [2 4 1 3 5 6]
% 矩阵排序matrix = [3, 1, 4; 1, 5, 9; 2, 6, 5];sorted_matrix = sort(matrix); % 按列排序sorted_matrix2 = sort(matrix, 2); % 按行排序4. 运算符详解
跳转到“4. 运算符详解”4.1 算术运算符
跳转到“4.1 算术运算符”4.1.1 标量运算
跳转到“4.1.1 标量运算”% 基本运算a = 10; b = 3;addition = a + b; % 加法:13subtraction = a - b; % 减法:7multiplication = a * b; % 乘法:30division = a / b; % 除法:3.3333power = a ^ b; % 幂运算:1000modulo = mod(a, b); % 取模:14.1.2 矩阵运算
跳转到“4.1.2 矩阵运算”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 * A4.1.3 逐元素运算(重要!)
跳转到“4.1.3 逐元素运算(重要!)”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 比较运算符
跳转到“4.2 比较运算符”a = 5; b = 3;A = [1, 2, 3; 4, 5, 6];B = [1, 0, 4; 4, 5, 0];
% 标量比较result1 = a > b; % trueresult2 = a == b; % falseresult3 = 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 逻辑运算符
跳转到“4.3 逻辑运算符”% 逻辑运算符a = true; b = false;result1 = a && b; % 逻辑与(短路):falseresult2 = a || b; % 逻辑或(短路):trueresult3 = ~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'); % 任意元素为真:trueresult_all_all = all(A, 'all'); % 所有元素为真:false4.4 位运算符
跳转到“4.4 位运算符”% 位运算a = 5; % 二进制:101b = 3; % 二进制:011
bit_and = bitand(a, b); % 位与:1bit_or = bitor(a, b); % 位或:7bit_xor = bitxor(a, b); % 位异或:6bit_not = bitcmp(a, 8); % 位非(8位):250bit_shift_left = bitshift(a, 2); % 左移2位:20bit_shift_right = bitshift(a, -1); % 右移1位:25. 控制结构
跳转到“5. 控制结构”5.1 条件语句
跳转到“5.1 条件语句”5.1.1 if-else语句
跳转到“5.1.1 if-else语句”% 基本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';endfprintf('成绩等级: %s\n', grade);
% 复合条件age = 25;income = 50000;if age >= 18 && income > 30000 disp('符合贷款条件');elseif age >= 18 || income > 100000 disp('需要进一步评估');else disp('不符合贷款条件');end5.1.2 switch-case语句
跳转到“5.1.2 switch-case语句”% 基本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 = '无效日期';endfprintf('今天是%s\n', day_name);
% 字符串switchoperation = '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;end5.2 循环结构
跳转到“5.2 循环结构”5.2.1 for循环
跳转到“5.2.1 for循环”% 基本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, 9end
% 递减循环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)); endend5.2.2 while循环
跳转到“5.2.2 while循环”% 基本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;endfprintf('和为%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);end5.2.3 循环控制语句
跳转到“5.2.3 循环控制语句”% 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
% 嵌套循环中的breakfor i = 1:3 for j = 1:3 if i == 2 && j == 2 break; % 只跳出内层循环 end fprintf('(%d, %d) ', i, j); end fprintf('\n');end5.3 异常处理
跳转到“5.3 异常处理”% 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); % 重新抛出错误 endend6. 函数编程
跳转到“6. 函数编程”6.1 函数基础
跳转到“6.1 函数基础”6.1.1 函数定义
跳转到“6.1.1 函数定义”% 基本函数定义(保存为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}; endend6.1.2 函数调用
跳转到“6.1.2 函数调用”% 调用基本函数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=50s_only = calculate(10, 5); % 只获取第一个输出
% 调用可变参数函数total = sum_all(1, 2, 3, 4, 5); % total = 156.2 高级函数特性
跳转到“6.2 高级函数特性”6.2.1 默认参数和参数检查
跳转到“6.2.1 默认参数和参数检查”% 使用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 嵌套函数和子函数
跳转到“6.2.2 嵌套函数和子函数”% 嵌套函数示例function main_function() % 主函数 x = 10; y = 5;
% 调用嵌套函数 result = nested_calculation(); fprintf('结果: %d\n', result);
% 嵌套函数可以访问主函数的变量 function output = nested_calculation() output = x + y; % 可以直接使用x和y endend
% 子函数示例(在同一个.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');end6.2.3 匿名函数和函数句柄
跳转到“6.2.3 匿名函数和函数句柄”% 匿名函数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 递归函数
跳转到“6.2.4 递归函数”% 阶乘函数function result = factorial_recursive(n) if n <= 1 result = 1; else result = n * factorial_recursive(n - 1); endend
% 斐波那契数列function result = fibonacci(n) if n <= 1 result = n; else result = fibonacci(n-1) + fibonacci(n-2); endend
% 优化的斐波那契(使用持久变量)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; endend7. 数据输入输出
跳转到“7. 数据输入输出”7.1 命令行输入输出
跳转到“7.1 命令行输入输出”% 显示输出disp('Hello, MATLAB!'); % 显示字符串disp([1, 2, 3, 4, 5]); % 显示数组
% 格式化输出name = 'Alice';age = 25;height = 1.65;fprintf('姓名: %s, 年龄: %d, 身高: %.2f米\n', name, age, height);
% 格式化字符串formatted_str = sprintf('圆周率: %.4f', pi);
% 用户输入user_input = input('请输入一个数字: ');user_string = input('请输入您的姓名: ', 's');
% 带提示的输入choice = input('请选择 (1-是, 0-否): ');if choice == 1 disp('您选择了是');else disp('您选择了否');end7.2 文件读写
跳转到“7.2 文件读写”7.2.1 文本文件操作
跳转到“7.2.1 文本文件操作”% 写入文本文件filename = 'example.txt';fileID = fopen(filename, 'w');if fileID == -1 error('无法创建文件');end
% 写入数据fprintf(fileID, '这是第一行\n');fprintf(fileID, '数字: %d, 小数: %.2f\n', 42, 3.14159);fclose(fileID);
% 读取文本文件fileID = fopen(filename, 'r');if fileID == -1 error('无法打开文件');end
% 逐行读取line_count = 0;while ~feof(fileID) line = fgetl(fileID); if ischar(line) line_count = line_count + 1; fprintf('第%d行: %s\n', line_count, line); endendfclose(fileID);
% 一次性读取所有内容content = fileread(filename);disp(content);7.2.2 CSV文件操作
跳转到“7.2.2 CSV文件操作”% 创建示例数据data = [1, 2, 3; 4, 5, 6; 7, 8, 9];headers = {'A', 'B', 'C'};
% 写入CSV文件writematrix(data, 'data.csv');
% 带标题的CSV写入T = table(data(:,1), data(:,2), data(:,3), 'VariableNames', headers);writetable(T, 'data_with_headers.csv');
% 读取CSV文件loaded_data = readmatrix('data.csv');loaded_table = readtable('data_with_headers.csv');
% 处理CSV数据fprintf('数据维度: %dx%d\n', size(loaded_data));fprintf('数据和: %.2f\n', sum(loaded_data, 'all'));7.2.3 Excel文件操作
跳转到“7.2.3 Excel文件操作”% 创建Excel文件data = rand(10, 5);column_names = {'列1', '列2', '列3', '列4', '列5'};T = table(data(:,1), data(:,2), data(:,3), data(:,4), data(:,5), ... 'VariableNames', column_names);
% 写入Excelwritetable(T, 'example.xlsx', 'Sheet', 'Sheet1');
% 读取Excelexcel_data = readtable('example.xlsx');excel_matrix = readmatrix('example.xlsx');
% 读取特定范围range_data = readmatrix('example.xlsx', 'Range', 'A1:C5');7.3 MAT文件操作
跳转到“7.3 MAT文件操作”% 保存变量到MAT文件a = [1, 2, 3];b = 'Hello';c = struct('name', 'Alice', 'age', 25);
% 保存所有变量save('data.mat');
% 保存特定变量save('specific_data.mat', 'a', 'b');
% 加载MAT文件clear; % 清除当前变量load('data.mat'); % 加载所有变量
% 加载特定变量load('data.mat', 'a'); % 只加载变量a
% 查看MAT文件内容file_info = whos('-file', 'data.mat');disp(file_info);8. 绘图与可视化
跳转到“8. 绘图与可视化”8.1 二维绘图
跳转到“8.1 二维绘图”8.1.1 基本绘图函数
跳转到“8.1.1 基本绘图函数”% 基本线图x = 0:0.1:2*pi;y = sin(x);figure;plot(x, y);title('正弦函数');xlabel('x');ylabel('sin(x)');grid on;
% 多条线图x = 0:0.1:2*pi;y1 = sin(x);y2 = cos(x);figure;plot(x, y1, 'r-', x, y2, 'b--');legend('sin(x)', 'cos(x)');title('三角函数');xlabel('x');ylabel('y');grid on;
% 散点图x = randn(100, 1);y = 2*x + randn(100, 1);figure;scatter(x, y, 50, 'filled');title('散点图');xlabel('x');ylabel('y');8.1.2 图形样式设置
跳转到“8.1.2 图形样式设置”% 线条样式x = 0:0.1:2*pi;y = sin(x);figure;plot(x, y, 'r-', 'LineWidth', 2, 'MarkerSize', 8);title('自定义样式', 'FontSize', 14, 'FontWeight', 'bold');xlabel('x', 'FontSize', 12);ylabel('sin(x)', 'FontSize', 12);grid on;set(gca, 'FontSize', 10);
% 颜色映射x = -2:0.1:2;y = -2:0.1:2;[X, Y] = meshgrid(x, y);Z = X.*exp(-X.^2-Y.^2);figure;contourf(X, Y, Z, 20);colorbar;title('等高线图');xlabel('x');ylabel('y');8.1.3 子图
跳转到“8.1.3 子图”% 创建子图figure;x = 0:0.1:2*pi;
% 子图1subplot(2, 2, 1);plot(x, sin(x));title('sin(x)');grid on;
% 子图2subplot(2, 2, 2);plot(x, cos(x));title('cos(x)');grid on;
% 子图3subplot(2, 2, 3);plot(x, tan(x));title('tan(x)');ylim([-5, 5]);grid on;
% 子图4subplot(2, 2, 4);plot(x, exp(-x));title('exp(-x)');grid on;8.2 三维绘图
跳转到“8.2 三维绘图”% 三维线图t = 0:0.1:3*pi;x = cos(t);y = sin(t);z = t;figure;plot3(x, y, z);title('三维螺旋线');xlabel('x');ylabel('y');zlabel('z');grid on;
% 三维曲面[X, Y] = meshgrid(-2:0.1:2, -2:0.1:2);Z = X.*exp(-X.^2-Y.^2);figure;surf(X, Y, Z);title('三维曲面');xlabel('x');ylabel('y');zlabel('z');colorbar;shading interp; % 平滑着色
% 三维散点图x = randn(100, 1);y = randn(100, 1);z = randn(100, 1);c = x + y + z; % 颜色数据figure;scatter3(x, y, z, 50, c, 'filled');title('三维散点图');xlabel('x');ylabel('y');zlabel('z');colorbar;8.3 特殊图形
跳转到“8.3 特殊图形”% 柱状图categories = {'A', 'B', 'C', 'D', 'E'};values = [23, 45, 56, 78, 32];figure;bar(values);set(gca, 'XTickLabel', categories);title('柱状图');ylabel('值');
% 饼图labels = {'类别1', '类别2', '类别3', '类别4'};sizes = [30, 25, 25, 20];figure;pie(sizes, labels);title('饼图');
% 直方图data = randn(1000, 1);figure;histogram(data, 30);title('直方图');xlabel('值');ylabel('频次');
% 箱线图groups = {'组1', '组2', '组3'};data1 = randn(100, 1);data2 = randn(100, 1) + 1;data3 = randn(100, 1) + 2;figure;boxplot([data1; data2; data3], [ones(100,1); 2*ones(100,1); 3*ones(100,1)]);set(gca, 'XTickLabel', groups);title('箱线图');ylabel('值');9. 字符串处理
跳转到“9. 字符串处理”9.1 字符串基础
跳转到“9.1 字符串基础”% 字符数组 vs 字符串数组char_array = 'Hello World'; % 字符数组string_array = "Hello World"; % 字符串数组
% 字符串长度len1 = length(char_array); % 11len2 = strlength(string_array); % 11
% 字符串连接% 字符数组连接combined_char = [char_array, ' MATLAB'];combined_char2 = strcat(char_array, ' MATLAB');
% 字符串数组连接combined_string = string_array + " MATLAB";combined_string2 = strcat(string_array, " MATLAB");9.2 字符串操作函数
跳转到“9.2 字符串操作函数”% 字符串查找text = "Hello World MATLAB";pos = strfind(text, "World"); % 查找位置contains_result = contains(text, "MATLAB"); % 是否包含starts_result = startsWith(text, "Hello"); % 是否以...开头ends_result = endsWith(text, "MATLAB"); % 是否以...结尾
% 字符串替换original = "Hello World";replaced = replace(original, "World", "MATLAB"); % "Hello MATLAB"
% 字符串分割sentence = "apple,banana,cherry";parts = split(sentence, ","); % ["apple"; "banana"; "cherry"]
% 字符串转换upper_text = upper("hello world"); % "HELLO WORLD"lower_text = lower("HELLO WORLD"); % "hello world"title_text = title("hello world"); % "Hello World"9.3 正则表达式
跳转到“9.3 正则表达式”% 正则表达式匹配text = "My phone number is 123-456-7890";pattern = '\d{3}-\d{3}-\d{4}';match = regexp(text, pattern, 'match'); % {'123-456-7890'}
% 提取数字text = "Price: $25.99, Tax: $2.60";numbers = regexp(text, '\d+\.\d+', 'match'); % {'25.99', '2.60'}
% 替换模式email = "contact@example.com";domain_pattern = '@\w+\.\w+';new_email = regexprep(email, domain_pattern, '@newdomain.com');9.4 字符串格式化
跳转到“9.4 字符串格式化”% sprintf格式化name = "Alice";age = 25;formatted = sprintf("姓名: %s, 年龄: %d", name, age);
% 现代字符串格式化formatted_modern = name + " is " + age + " years old";
% 数值格式化pi_formatted = sprintf("π ≈ %.4f", pi);
% 日期格式化current_date = datetime('now');date_string = string(current_date, 'yyyy-MM-dd HH:mm:ss');10. 结构体与元胞数组
跳转到“10. 结构体与元胞数组”10.1 结构体
跳转到“10.1 结构体”10.1.1 结构体创建和访问
跳转到“10.1.1 结构体创建和访问”% 创建结构体student.name = 'Alice';student.age = 20;student.scores = [85, 92, 78];
% 或者使用struct函数student2 = struct('name', 'Bob', 'age', 21, 'scores', [90, 88, 95]);
% 访问结构体字段fprintf('学生姓名: %s\n', student.name);fprintf('平均分: %.2f\n', mean(student.scores));10.1.2 结构体数组
跳转到“10.1.2 结构体数组”% 创建结构体数组students(1) = struct('name', 'Alice', 'age', 20, 'scores', [85, 92, 78]);students(2) = struct('name', 'Bob', 'age', 21, 'scores', [90, 88, 95]);students(3) = struct('name', 'Charlie', 'age', 19, 'scores', [88, 90, 92]);
% 访问结构体数组for i = 1:length(students) fprintf('学生%d: %s, 年龄: %d, 平均分: %.2f\n', ... i, students(i).name, students(i).age, mean(students(i).scores));end
% 提取特定字段names = {students.name}; % 所有姓名ages = [students.age]; % 所有年龄10.1.3 嵌套结构体
跳转到“10.1.3 嵌套结构体”% 嵌套结构体company.name = 'Tech Corp';company.employees(1).name = 'Alice';company.employees(1).position = 'Engineer';company.employees(1).salary = 75000;company.employees(2).name = 'Bob';company.employees(2).position = 'Manager';company.employees(2).salary = 85000;
% 访问嵌套结构体fprintf('公司: %s\n', company.name);for i = 1:length(company.employees) emp = company.employees(i); fprintf('员工%d: %s, 职位: %s, 薪资: $%d\n', ... i, emp.name, emp.position, emp.salary);end10.2 元胞数组
跳转到“10.2 元胞数组”10.2.1 元胞数组创建
跳转到“10.2.1 元胞数组创建”% 创建元胞数组cell_array = {'Hello', 42, [1, 2, 3], true};
% 预分配元胞数组large_cell = cell(3, 3);large_cell{1, 1} = 'Text';large_cell{1, 2} = 123;large_cell{2, 1} = [1, 2, 3; 4, 5, 6];
% 混合数据类型mixed_data = { 'Name', 'Alice'; 'Age', 25; 'Scores', [85, 92, 78]; 'Graduate', true};10.2.2 元胞数组操作
跳转到“10.2.2 元胞数组操作”% 访问元胞数组first_element = cell_array{1}; % 'Hello'second_element = cell_array{2}; % 42
% 修改元胞数组cell_array{1} = 'Modified';
% 元胞数组大小[rows, cols] = size(mixed_data);total_elements = numel(cell_array);
% 元胞数组转换if all(cellfun(@isnumeric, cell_array(2:3))) numeric_part = cell2mat(cell_array(2:3));end10.2.3 元胞数组的高级操作
跳转到“10.2.3 元胞数组的高级操作”% 使用cellfun处理元胞数组numbers_cell = {[1, 2, 3], [4, 5], [6, 7, 8, 9]};lengths = cellfun(@length, numbers_cell); % [3, 2, 4]means = cellfun(@mean, numbers_cell); % [2, 4.5, 6.5]
% 字符串元胞数组操作names = {'Alice', 'Bob', 'Charlie'};name_lengths = cellfun(@length, names);upper_names = cellfun(@upper, names, 'UniformOutput', false);
% 元胞数组排序[sorted_names, indices] = sort(names);11. 文件操作
跳转到“11. 文件操作”11.1 文件系统操作
跳转到“11.1 文件系统操作”% 当前目录操作current_dir = pwd; % 获取当前目录cd('/path/to/directory'); % 改变目录cd(current_dir); % 返回原目录
% 文件和目录信息file_info = dir('*.m'); % 列出所有.m文件folder_info = dir(); % 列出当前目录所有内容
% 检查文件/目录存在性if exist('data.mat', 'file') disp('文件存在');end
if exist('my_folder', 'dir') disp('目录存在');end
% 创建和删除目录if ~exist('temp_folder', 'dir') mkdir('temp_folder');endrmdir('temp_folder'); % 删除空目录11.2 文件路径操作
跳转到“11.2 文件路径操作”% 路径构建full_path = fullfile('data', 'results', 'output.txt');
% 路径分析[path, name, ext] = fileparts(full_path);fprintf('路径: %s\n', path);fprintf('文件名: %s\n', name);fprintf('扩展名: %s\n', ext);
% 相对路径和绝对路径relative_path = 'data/file.txt';absolute_path = fullfile(pwd, relative_path);11.3 批量文件处理
跳转到“11.3 批量文件处理”% 批量处理文件file_list = dir('*.txt');for i = 1:length(file_list) filename = file_list(i).name; fprintf('处理文件: %s\n', filename);
% 读取文件 content = fileread(filename);
% 处理内容(示例:转换为大写) processed_content = upper(content);
% 保存处理后的文件 new_filename = ['processed_', filename]; fid = fopen(new_filename, 'w'); fprintf(fid, '%s', processed_content); fclose(fid);end12. 调试与错误处理
跳转到“12. 调试与错误处理”12.1 调试技巧
跳转到“12.1 调试技巧”% 断点调试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 endend12.2 错误处理策略
跳转到“12.2 错误处理策略”% 完整的错误处理示例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 endend
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);end13. 性能优化
跳转到“13. 性能优化”13.1 向量化操作
跳转到“13.1 向量化操作”% 避免循环,使用向量化% 低效的循环方式tic;n = 1000000;result_loop = zeros(n, 1);for i = 1:n result_loop(i) = sin(i) + cos(i);endtime_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 内存管理
跳转到“13.2 内存管理”% 预分配数组% 低效方式tic;slow_array = [];for i = 1:10000 slow_array(end+1) = i^2;endtime_slow = toc;
% 高效方式tic;fast_array = zeros(10000, 1);for i = 1:10000 fast_array(i) = i^2;endtime_fast = toc;
fprintf('动态分配时间: %.4f秒\n', time_slow);fprintf('预分配时间: %.4f秒\n', time_fast);13.3 性能分析
跳转到“13.3 性能分析”% 使用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);end14. 工具箱简介
跳转到“14. 工具箱简介”14.1 常用工具箱
跳转到“14.1 常用工具箱”14.1.1 Signal Processing Toolbox(信号处理工具箱)
跳转到“14.1.1 Signal Processing Toolbox(信号处理工具箱)”% 信号处理示例fs = 1000; % 采样频率t = 0:1/fs:1-1/fs; % 时间向量f1 = 50; f2 = 120; % 频率signal = sin(2*pi*f1*t) + 0.5*sin(2*pi*f2*t);
% 添加噪声noisy_signal = signal + 0.2*randn(size(t));
% 设计滤波器[b, a] = butter(4, 100/(fs/2)); % 4阶低通滤波器filtered_signal = filter(b, a, noisy_signal);
% 绘图figure;subplot(3,1,1);plot(t, signal);title('原始信号');
subplot(3,1,2);plot(t, noisy_signal);title('带噪声信号');
subplot(3,1,3);plot(t, filtered_signal);title('滤波后信号');
% 频谱分析figure;Y = fft(noisy_signal);f = (0:length(Y)-1)*fs/length(Y);plot(f, abs(Y));title('频谱分析');xlabel('频率 (Hz)');ylabel('幅度');14.1.2 Image Processing Toolbox(图像处理工具箱)
跳转到“14.1.2 Image Processing Toolbox(图像处理工具箱)”% 图像处理示例% 读取图像img = imread('cameraman.tif'); % MATLAB自带图像figure;subplot(2,3,1);imshow(img);title('原图');
% 直方图均衡化img_eq = histeq(img);subplot(2,3,2);imshow(img_eq);title('直方图均衡化');
% 边缘检测edges = edge(img, 'canny');subplot(2,3,3);imshow(edges);title('边缘检测');
% 高斯滤波img_filtered = imgaussfilt(img, 2);subplot(2,3,4);imshow(img_filtered);title('高斯滤波');
% 形态学操作se = strel('disk', 3);img_morph = imopen(img, se);subplot(2,3,5);imshow(img_morph);title('形态学开运算');
% 图像分割level = graythresh(img);img_bw = imbinarize(img, level);subplot(2,3,6);imshow(img_bw);title('二值化');14.1.3 Statistics and Machine Learning Toolbox(统计和机器学习工具箱)
跳转到“14.1.3 Statistics and Machine Learning Toolbox(统计和机器学习工具箱)”% 统计分析示例rng(42); % 设置随机种子data = randn(1000, 2);data(:,2) = data(:,2) + 0.5*data(:,1); % 添加相关性
% 描述性统计mean_vals = mean(data);std_vals = std(data);corr_matrix = corrcoef(data);
fprintf('均值: [%.2f, %.2f]\n', mean_vals(1), mean_vals(2));fprintf('标准差: [%.2f, %.2f]\n', std_vals(1), std_vals(2));fprintf('相关系数: %.2f\n', corr_matrix(1,2));
% 机器学习示例 - 聚类% 生成聚类数据cluster1 = mvnrnd([2, 2], [1, 0.5; 0.5, 1], 100);cluster2 = mvnrnd([-2, -2], [1, -0.5; -0.5, 1], 100);cluster3 = mvnrnd([2, -2], [1, 0; 0, 1], 100);ml_data = [cluster1; cluster2; cluster3];
% K-means聚类[idx, centers] = kmeans(ml_data, 3);
% 可视化聚类结果figure;colors = ['r', 'g', 'b'];for i = 1:3 scatter(ml_data(idx==i, 1), ml_data(idx==i, 2), colors(i), 'filled'); hold on;endscatter(centers(:,1), centers(:,2), 100, 'k', 'x', 'LineWidth', 2);title('K-means聚类结果');legend('聚类1', '聚类2', '聚类3', '聚类中心');14.1.4 Optimization Toolbox(优化工具箱)
跳转到“14.1.4 Optimization Toolbox(优化工具箱)”% 优化问题示例% 目标函数:最小化 f(x) = x1^2 + x2^2 + x1*x2objective = @(x) x(1)^2 + x(2)^2 + x(1)*x(2);
% 初始点x0 = [1, 1];
% 约束条件% 不等式约束: x1 + x2 <= 2A = [1, 1];b = 2;
% 等式约束: x1 - x2 = 0Aeq = [1, -1];beq = 0;
% 求解options = optimoptions('fmincon', 'Display', 'iter');[x_optimal, fval] = fmincon(objective, x0, A, b, Aeq, beq, [], [], [], options);
fprintf('最优解: x = [%.4f, %.4f]\n', x_optimal(1), x_optimal(2));fprintf('最优值: f = %.4f\n', fval);14.1.5 Control System Toolbox(控制系统工具箱)
跳转到“14.1.5 Control System Toolbox(控制系统工具箱)”% 控制系统示例% 传递函数num = [1, 2];den = [1, 3, 2];sys = tf(num, den);
% 系统分析figure;subplot(2,2,1);step(sys);title('阶跃响应');
subplot(2,2,2);impulse(sys);title('脉冲响应');
subplot(2,2,3);bode(sys);title('波德图');
subplot(2,2,4);nyquist(sys);title('奈奎斯特图');
% 极点和零点poles = pole(sys);zeros = zero(sys);fprintf('极点: ');disp(poles');fprintf('零点: ');disp(zeros');14.2 工具箱函数查找
跳转到“14.2 工具箱函数查找”% 查看已安装的工具箱ver
% 查看特定工具箱的函数help signal % 信号处理工具箱help images % 图像处理工具箱help stats % 统计工具箱
% 搜索特定功能lookfor filter % 搜索包含"filter"的函数15. 实战项目
跳转到“15. 实战项目”15.1 项目1:数据分析与可视化
跳转到“15.1 项目1:数据分析与可视化”% 项目:分析股票数据% 生成模拟股票数据days = 1:252; % 一年的交易日initial_price = 100;returns = 0.001 + 0.02*randn(1, 252); % 日收益率prices = initial_price * cumprod(1 + returns);
% 计算技术指标function sma = simple_moving_average(data, window) sma = zeros(size(data)); for i = window:length(data) sma(i) = mean(data(i-window+1:i)); endend
sma_20 = simple_moving_average(prices, 20);sma_50 = simple_moving_average(prices, 50);
% 计算波动率volatility = movstd(returns, 20) * sqrt(252);
% 绘制分析图表figure('Position', [100, 100, 1200, 800]);
% 价格和移动平均线subplot(3,1,1);plot(days, prices, 'b-', 'LineWidth', 1.5);hold on;plot(days, sma_20, 'r--', 'LineWidth', 1);plot(days, sma_50, 'g--', 'LineWidth', 1);title('股票价格和移动平均线');legend('价格', '20日均线', '50日均线');ylabel('价格');grid on;
% 日收益率subplot(3,1,2);plot(days, returns*100, 'k-');title('日收益率');ylabel('收益率 (%)');grid on;
% 波动率subplot(3,1,3);plot(days, volatility*100, 'm-', 'LineWidth', 1.5);title('20日滚动波动率');ylabel('波动率 (%)');xlabel('交易日');grid on;
% 统计摘要fprintf('=== 股票分析报告 ===\n');fprintf('期初价格: $%.2f\n', prices(1));fprintf('期末价格: $%.2f\n', prices(end));fprintf('总收益率: %.2f%%\n', (prices(end)/prices(1) - 1)*100);fprintf('平均日收益率: %.4f%%\n', mean(returns)*100);fprintf('波动率: %.2f%%\n', std(returns)*sqrt(252)*100);fprintf('最大回撤: %.2f%%\n', max(cummax(prices) - prices)./cummax(prices)*100);15.2 项目2:信号处理应用
跳转到“15.2 项目2:信号处理应用”% 项目:音频信号处理% 生成复合音频信号fs = 44100; % 采样率duration = 3; % 持续时间t = 0:1/fs:duration-1/fs;
% 创建复合信号freq1 = 440; % A4音符freq2 = 880; % A5音符freq3 = 1320; % E6音符signal = sin(2*pi*freq1*t) + 0.5*sin(2*pi*freq2*t) + 0.3*sin(2*pi*freq3*t);
% 添加噪声noisy_signal = signal + 0.1*randn(size(t));
% 设计滤波器组% 低通滤波器 (< 600 Hz)[b_low, a_low] = butter(6, 600/(fs/2), 'low');low_freq = filter(b_low, a_low, noisy_signal);
% 带通滤波器 (600-1000 Hz)[b_band, a_band] = butter(6, [600, 1000]/(fs/2), 'bandpass');mid_freq = filter(b_band, a_band, noisy_signal);
% 高通滤波器 (> 1000 Hz)[b_high, a_high] = butter(6, 1000/(fs/2), 'high');high_freq = filter(b_high, a_high, noisy_signal);
% 频谱分析N = length(noisy_signal);f = (0:N-1)*(fs/N);Y_original = fft(signal);Y_noisy = fft(noisy_signal);Y_filtered = fft(low_freq + mid_freq + high_freq);
% 绘制结果figure('Position', [100, 100, 1200, 900]);
% 时域信号subplot(3,2,1);plot(t(1:fs/10), signal(1:fs/10));title('原始信号(前0.1秒)');xlabel('时间 (s)');ylabel('幅度');
subplot(3,2,2);plot(t(1:fs/10), noisy_signal(1:fs/10));title('含噪声信号(前0.1秒)');xlabel('时间 (s)');ylabel('幅度');
% 频谱subplot(3,2,3);plot(f(1:N/2), abs(Y_original(1:N/2)));title('原始信号频谱');xlabel('频率 (Hz)');ylabel('幅度');
subplot(3,2,4);plot(f(1:N/2), abs(Y_noisy(1:N/2)));title('含噪声信号频谱');xlabel('频率 (Hz)');ylabel('幅度');
% 滤波后的信号subplot(3,2,5);plot(t(1:fs/10), (low_freq + mid_freq + high_freq)(1:fs/10));title('滤波后信号(前0.1秒)');xlabel('时间 (s)');ylabel('幅度');
subplot(3,2,6);plot(f(1:N/2), abs(Y_filtered(1:N/2)));title('滤波后信号频谱');xlabel('频率 (Hz)');ylabel('幅度');
% 保存音频文件(如果需要)% audiowrite('original_signal.wav', signal, fs);% audiowrite('noisy_signal.wav', noisy_signal, fs);% audiowrite('filtered_signal.wav', low_freq + mid_freq + high_freq, fs);15.3 项目3:图像处理应用
跳转到“15.3 项目3:图像处理应用”% 项目:图像增强和特征提取% 读取图像(使用MATLAB自带的图像)img = imread('coins.png');if size(img, 3) == 3 img_gray = rgb2gray(img);else img_gray = img;end
% 图像预处理img_enhanced = imadjust(img_gray); % 对比度增强img_filtered = imgaussfilt(img_enhanced, 1); % 高斯滤波
% 边缘检测edges = edge(img_filtered, 'canny');
% 形态学处理se = strel('disk', 3);img_closed = imclose(edges, se);img_filled = imfill(img_closed, 'holes');
% 连通组件分析[labeled, num_objects] = bwlabel(img_filled);stats = regionprops(labeled, 'Area', 'Centroid', 'BoundingBox', 'Eccentricity');
% 过滤小对象min_area = 500;large_objects = [stats.Area] > min_area;stats_filtered = stats(large_objects);
% 创建结果图像result_img = img_gray;figure('Position', [100, 100, 1200, 800]);
% 显示处理过程subplot(2,3,1);imshow(img_gray);title('原图');
subplot(2,3,2);imshow(img_enhanced);title('对比度增强');
subplot(2,3,3);imshow(edges);title('边缘检测');
subplot(2,3,4);imshow(img_filled);title('形态学处理');
subplot(2,3,5);imshow(img_gray);hold on;for i = 1:length(stats_filtered) centroid = stats_filtered(i).Centroid; plot(centroid(1), centroid(2), 'r+', 'MarkerSize', 10, 'LineWidth', 2);
% 绘制边界框 bbox = stats_filtered(i).BoundingBox; rectangle('Position', bbox, 'EdgeColor', 'g', 'LineWidth', 2);endtitle(sprintf('检测到的对象 (共%d个)', length(stats_filtered)));
subplot(2,3,6);areas = [stats_filtered.Area];histogram(areas, 10);title('对象面积分布');xlabel('面积 (像素)');ylabel('数量');
% 输出统计信息fprintf('=== 图像分析报告 ===\n');fprintf('图像尺寸: %d × %d\n', size(img_gray, 1), size(img_gray, 2));fprintf('检测到的对象数量: %d\n', length(stats_filtered));fprintf('平均对象面积: %.2f 像素\n', mean(areas));fprintf('最大对象面积: %.2f 像素\n', max(areas));fprintf('最小对象面积: %.2f 像素\n', min(areas));15.4 项目4:数值计算应用
跳转到“15.4 项目4:数值计算应用”% 项目:求解偏微分方程(热传导方程)% 参数设置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)); endend
% 解析解(用于验证)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;endtitle('不同时间点的温度分布');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. 常见问题与解决方案”16.1 常见错误及解决方法
跳转到“16.1 常见错误及解决方法”16.1.1 索引错误
跳转到“16.1.1 索引错误”% 错误示例A = [1, 2, 3];try value = A(0); % MATLAB索引从1开始,不是0catch 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);end16.1.2 维度不匹配
跳转到“16.1.2 维度不匹配”% 错误示例A = [1, 2, 3]; % 1×3B = [4; 5; 6]; % 3×1try 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 数据类型问题
跳转到“16.1.3 数据类型问题”% 整数溢出a = uint8(255);b = uint8(10);c = a + b; % 溢出,结果为255而不是265fprintf('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);16.2 性能问题诊断
跳转到“16.2 性能问题诊断”16.2.1 内存使用监控
跳转到“16.2.1 内存使用监控”% 监控内存使用function memory_demo() % 获取当前内存使用 memory_info = memory; fprintf('可用内存: %.2f GB\n', memory_info.MemAvailableAllArrays / 1e9);
% 创建大数组 fprintf('创建大数组...\n'); big_array = randn(10000, 10000);
% 检查内存使用 memory_info = memory; fprintf('使用后可用内存: %.2f GB\n', memory_info.MemAvailableAllArrays / 1e9);
% 清理内存 clear big_array; fprintf('清理后可用内存: %.2f GB\n', memory.MemAvailableAllArrays / 1e9);end
memory_demo();16.2.2 代码剖析
跳转到“16.2.2 代码剖析”% 性能测试函数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 调试技巧”16.3.1 断点和单步执行
跳转到“16.3.1 断点和单步执行”% 调试示例函数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 异常处理
跳转到“16.3.2 异常处理”% 健壮的异常处理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'); endend
% 测试异常处理robust_calculation([1, 2, 3, NaN, 5]);robust_calculation('invalid');16.4 最佳实践总结
跳转到“16.4 最佳实践总结”16.4.1 编程风格
跳转到“16.4.1 编程风格”% 好的编程风格示例function [mean_val, std_val, processed_data] = process_data(input_data, options) % PROCESS_DATA 处理输入数据并返回统计信息 % % 输入: % input_data - 数值数组 % options - 处理选项结构体 % % 输出: % mean_val - 平均值 % std_val - 标准差 % processed_data - 处理后的数据
% 输入验证 arguments input_data (:,:) double options.remove_outliers (1,1) logical = false options.normalize (1,1) logical = false end
% 初始化 processed_data = input_data;
% 移除异常值 if options.remove_outliers q1 = quantile(processed_data, 0.25); q3 = quantile(processed_data, 0.75); iqr = q3 - q1; outliers = processed_data < (q1 - 1.5*iqr) | processed_data > (q3 + 1.5*iqr); processed_data(outliers) = NaN; end
% 标准化 if options.normalize processed_data = (processed_data - mean(processed_data, 'omitnan')) / ... std(processed_data, 'omitnan'); end
% 计算统计量 mean_val = mean(processed_data, 'omitnan'); std_val = std(processed_data, 'omitnan');
% 记录处理信息 fprintf('处理完成: 均值=%.4f, 标准差=%.4f\n', mean_val, std_val);end
% 使用示例data = randn(1000, 1) + [zeros(950, 1); 10*ones(50, 1)]; % 包含异常值[m, s, clean_data] = process_data(data, 'remove_outliers', true, 'normalize', true);16.4.2 代码组织
跳转到“16.4.2 代码组织”% 主函数function main() % 设置参数 config = load_config();
% 加载数据 data = load_data(config.data_file);
% 处理数据 results = process_all_data(data, config);
% 保存结果 save_results(results, config.output_file);
% 生成报告 generate_report(results);end
% 配置加载函数function config = load_config() config.data_file = 'input_data.mat'; config.output_file = 'results.mat'; config.processing_options.filter_type = 'gaussian'; config.processing_options.window_size = 10; config.visualization.create_plots = true; config.visualization.save_figures = true;end
% 数据加载函数function data = load_data(filename) if exist(filename, 'file') load(filename, 'data'); else warning('数据文件不存在,使用模拟数据'); data = generate_sample_data(); endend
% 数据处理函数function results = process_all_data(data, config) results = struct(); results.raw_statistics = calculate_statistics(data); results.filtered_data = apply_filter(data, config.processing_options); results.processed_statistics = calculate_statistics(results.filtered_data);
if config.visualization.create_plots results.figures = create_visualizations(data, results.filtered_data); endend16.5 高级技巧和技术
跳转到“16.5 高级技巧和技术”16.5.1 面向对象编程
跳转到“16.5.1 面向对象编程”% 定义一个数据分析类classdef DataAnalyzer < handle % DATAANALYZER 数据分析器类
properties (Access = public) data % 原始数据 processed_data % 处理后的数据 statistics % 统计信息 options % 处理选项 end
properties (Access = private) is_processed = false % 是否已处理 end
methods function obj = DataAnalyzer(input_data, varargin) % 构造函数 obj.data = input_data; obj.options = obj.parse_options(varargin{:}); obj.statistics = struct(); end
function process(obj) % 处理数据 obj.processed_data = obj.data;
% 移除异常值 if obj.options.remove_outliers obj.processed_data = obj.remove_outliers(obj.processed_data); end
% 应用滤波 if ~isempty(obj.options.filter_type) obj.processed_data = obj.apply_filter(obj.processed_data); end
% 计算统计量 obj.calculate_statistics(); obj.is_processed = true; end
function visualize(obj) % 可视化结果 if ~obj.is_processed error('请先调用process()方法'); end
figure('Position', [100, 100, 1200, 600]);
subplot(2,2,1); plot(obj.data); title('原始数据'); ylabel('值');
subplot(2,2,2); plot(obj.processed_data); title('处理后数据'); ylabel('值');
subplot(2,2,3); histogram(obj.data, 30); title('原始数据直方图'); xlabel('值'); ylabel('频数');
subplot(2,2,4); histogram(obj.processed_data, 30); title('处理后数据直方图'); xlabel('值'); ylabel('频数'); end
function report = generate_report(obj) % 生成报告 if ~obj.is_processed error('请先调用process()方法'); end
report = struct(); report.original_stats = obj.statistics.original; report.processed_stats = obj.statistics.processed; report.improvement = obj.calculate_improvement();
% 打印报告 fprintf('\n=== 数据分析报告 ===\n'); fprintf('原始数据统计:\n'); fprintf(' 均值: %.4f\n', report.original_stats.mean); fprintf(' 标准差: %.4f\n', report.original_stats.std); fprintf(' 范围: [%.4f, %.4f]\n', report.original_stats.min, report.original_stats.max);
fprintf('\n处理后数据统计:\n'); fprintf(' 均值: %.4f\n', report.processed_stats.mean); fprintf(' 标准差: %.4f\n', report.processed_stats.std); fprintf(' 范围: [%.4f, %.4f]\n', report.processed_stats.min, report.processed_stats.max);
fprintf('\n改善情况:\n'); fprintf(' 标准差减少: %.2f%%\n', report.improvement.std_reduction * 100); fprintf(' 信噪比提升: %.2f dB\n', report.improvement.snr_improvement); end end
methods (Access = private) function options = parse_options(obj, varargin) % 解析输入选项 p = inputParser; addParameter(p, 'remove_outliers', false, @islogical); addParameter(p, 'filter_type', 'none', @ischar); addParameter(p, 'filter_window', 5, @isnumeric); parse(p, varargin{:}); options = p.Results; end
function data = remove_outliers(obj, data) % 移除异常值 q1 = quantile(data, 0.25); q3 = quantile(data, 0.75); iqr = q3 - q1; outliers = data < (q1 - 1.5*iqr) | data > (q3 + 1.5*iqr); data(outliers) = NaN; end
function data = apply_filter(obj, data) % 应用滤波器 switch obj.options.filter_type case 'moving_average' data = movmean(data, obj.options.filter_window, 'omitnan'); case 'gaussian' data = smoothdata(data, 'gaussian', obj.options.filter_window); case 'median' data = movmedian(data, obj.options.filter_window, 'omitnan'); end end
function calculate_statistics(obj) % 计算统计量 obj.statistics.original = obj.compute_stats(obj.data); obj.statistics.processed = obj.compute_stats(obj.processed_data); end
function stats = compute_stats(obj, data) % 计算基本统计量 stats.mean = mean(data, 'omitnan'); stats.std = std(data, 'omitnan'); stats.min = min(data, [], 'omitnan'); stats.max = max(data, [], 'omitnan'); stats.median = median(data, 'omitnan'); stats.count = sum(~isnan(data)); end
function improvement = calculate_improvement(obj) % 计算改善指标 original_std = obj.statistics.original.std; processed_std = obj.statistics.processed.std;
improvement.std_reduction = (original_std - processed_std) / original_std; improvement.snr_improvement = 20 * log10(original_std / processed_std); end endend
% 使用示例data = randn(1000, 1) + 0.5*sin(0.1*(1:1000)') + [zeros(950, 1); 5*randn(50, 1)];analyzer = DataAnalyzer(data, 'remove_outliers', true, 'filter_type', 'gaussian', 'filter_window', 10);analyzer.process();analyzer.visualize();report = analyzer.generate_report();16.5.2 并行计算
跳转到“16.5.2 并行计算”% 并行计算示例function parallel_computing_demo() % 检查并行计算工具箱 if ~license('test', 'Distrib_Computing_Toolbox') warning('未安装并行计算工具箱'); return; end
% 启动并行池 if isempty(gcp('nocreate')) parpool('local', 4); % 启动4个工作进程 end
% 数据准备 n = 1000; matrices = cell(n, 1); for i = 1:n matrices{i} = randn(100, 100); end
% 串行计算 tic; serial_results = zeros(n, 1); for i = 1:n serial_results(i) = det(matrices{i}); end serial_time = toc;
% 并行计算 tic; parallel_results = zeros(n, 1); parfor i = 1:n parallel_results(i) = det(matrices{i}); end parallel_time = toc;
% 比较结果 fprintf('串行计算时间: %.4f 秒\n', serial_time); fprintf('并行计算时间: %.4f 秒\n', parallel_time); fprintf('加速比: %.2f\n', serial_time / parallel_time); fprintf('结果一致性: %s\n', mat2str(norm(serial_results - parallel_results) < 1e-10));end
% 并行数据处理示例function parallel_data_processing() % 生成大量数据集 num_datasets = 20; datasets = cell(num_datasets, 1); for i = 1:num_datasets datasets{i} = randn(10000, 1) + sin(0.01*(1:10000)'); end
% 并行处理函数 function result = process_dataset(data) % 复杂的数据处理 filtered = smoothdata(data, 'gaussian', 50); fft_result = fft(filtered); power_spectrum = abs(fft_result).^2; result = struct('mean', mean(data), 'std', std(data), ... 'max_freq', max(power_spectrum), 'energy', sum(power_spectrum)); end
% 并行处理 tic; results = cell(num_datasets, 1); parfor i = 1:num_datasets results{i} = process_dataset(datasets{i}); end parallel_time = toc;
fprintf('并行处理%d个数据集用时: %.4f 秒\n', num_datasets, parallel_time);
% 汇总结果 means = cellfun(@(x) x.mean, results); stds = cellfun(@(x) x.std, results);
fprintf('平均值范围: [%.4f, %.4f]\n', min(means), max(means)); fprintf('标准差范围: [%.4f, %.4f]\n', min(stds), max(stds));end
% 运行并行计算示例parallel_computing_demo();parallel_data_processing();16.5.3 GPU计算
跳转到“16.5.3 GPU计算”% GPU计算示例function gpu_computing_demo() % 检查GPU支持 if ~canUseGPU() warning('GPU不可用或未安装Parallel Computing Toolbox'); return; end
% 显示GPU信息 gpu_info = gpuDevice(); fprintf('GPU: %s\n', gpu_info.Name); fprintf('GPU内存: %.2f GB\n', gpu_info.TotalMemory / 1e9);
% 创建大矩阵 n = 5000; A_cpu = randn(n, n); B_cpu = randn(n, n);
% CPU计算 tic; C_cpu = A_cpu * B_cpu; cpu_time = toc;
% GPU计算 A_gpu = gpuArray(A_cpu); B_gpu = gpuArray(B_cpu);
tic; C_gpu = A_gpu * B_gpu; wait(gpu_info); % 等待GPU计算完成 gpu_time = toc;
% 将结果传回CPU C_gpu_result = gather(C_gpu);
% 比较结果 fprintf('CPU计算时间: %.4f 秒\n', cpu_time); fprintf('GPU计算时间: %.4f 秒\n', gpu_time); fprintf('加速比: %.2f\n', cpu_time / gpu_time); fprintf('结果误差: %.2e\n', norm(C_cpu - C_gpu_result, 'fro') / norm(C_cpu, 'fro'));
% 清理GPU内存 clear A_gpu B_gpu C_gpu;end
% GPU信号处理示例function gpu_signal_processing() if ~canUseGPU() return; end
% 生成信号 fs = 1000; t = 0:1/fs:10-1/fs; signal_cpu = sin(2*pi*50*t) + 0.5*sin(2*pi*120*t) + 0.2*randn(size(t));
% 传输到GPU signal_gpu = gpuArray(signal_cpu);
% GPU上的FFT tic; fft_gpu = fft(signal_gpu); power_spectrum_gpu = abs(fft_gpu).^2; gpu_fft_time = toc;
% CPU上的FFT tic; fft_cpu = fft(signal_cpu); power_spectrum_cpu = abs(fft_cpu).^2; cpu_fft_time = toc;
fprintf('CPU FFT时间: %.6f 秒\n', cpu_fft_time); fprintf('GPU FFT时间: %.6f 秒\n', gpu_fft_time);
% 验证结果 power_spectrum_gpu_result = gather(power_spectrum_gpu); fprintf('FFT结果误差: %.2e\n', norm(power_spectrum_cpu - power_spectrum_gpu_result) / norm(power_spectrum_cpu));end
% 如果有GPU,运行GPU计算示例if canUseGPU() gpu_computing_demo(); gpu_signal_processing();end16.6 与其他语言的接口
跳转到“16.6 与其他语言的接口”16.6.1 调用Python代码
跳转到“16.6.1 调用Python代码”% 调用Python示例function python_interface_demo() % 检查Python环境 try pyenv; fprintf('Python环境已配置\n'); catch fprintf('Python环境未配置,请先配置Python\n'); return; end
% 调用Python内置函数 py_list = py.list({1, 2, 3, 4, 5}); py_sum = py.sum(py_list); fprintf('Python list sum: %d\n', py_sum);
% 调用Python的NumPy try np = py.importlib.import_module('numpy');
% 创建NumPy数组 data_matlab = [1, 2, 3; 4, 5, 6]; data_numpy = np.array(data_matlab);
% 使用NumPy函数 numpy_mean = np.mean(data_numpy); numpy_std = np.std(data_numpy);
fprintf('NumPy mean: %.4f\n', numpy_mean); fprintf('NumPy std: %.4f\n', numpy_std);
% 比较MATLAB和NumPy结果 matlab_mean = mean(data_matlab, 'all'); matlab_std = std(data_matlab, 0, 'all');
fprintf('MATLAB mean: %.4f\n', matlab_mean); fprintf('MATLAB std: %.4f\n', matlab_std);
catch ME fprintf('NumPy not available: %s\n', ME.message); endend
% 调用Python机器学习function python_ml_demo() try % 导入scikit-learn sklearn = py.importlib.import_module('sklearn'); datasets = py.importlib.import_module('sklearn.datasets'); model_selection = py.importlib.import_module('sklearn.model_selection'); svm = py.importlib.import_module('sklearn.svm');
% 加载数据 iris = datasets.load_iris(); X = double(iris.data); y = double(iris.target);
% 划分训练测试集 split_result = model_selection.train_test_split(iris.data, iris.target, ... pyargs('test_size', 0.3, 'random_state', 42)); X_train = double(split_result{1}); X_test = double(split_result{2}); y_train = double(split_result{3}); y_test = double(split_result{4});
% 训练SVM模型 clf = svm.SVC(pyargs('kernel', 'rbf', 'C', 1.0)); clf.fit(X_train, y_train);
% 预测 y_pred = clf.predict(X_test); y_pred_matlab = double(y_pred);
% 计算准确率 accuracy = sum(y_test == y_pred_matlab) / length(y_test); fprintf('SVM分类准确率: %.4f\n', accuracy);
catch ME fprintf('Scikit-learn not available: %s\n', ME.message); endend
% 运行Python接口示例python_interface_demo();python_ml_demo();16.6.2 调用C/C++代码
跳转到“16.6.2 调用C/C++代码”% MEX文件示例% 首先需要创建一个C文件,例如matrix_multiply.cfunction create_mex_example() % 创建C代码文件 c_code = sprintf([ '#include "mex.h"\n'... '#include <string.h>\n'... '\n'... 'void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])\n'... '{\n'... ' double *A, *B, *C;\n'... ' int m, n, p;\n'... ' int i, j, k;\n'... ' \n'... ' /* 检查输入参数 */\n'... ' if (nrhs != 2) {\n'... ' mexErrMsgIdAndTxt("MyToolbox:matrix_multiply:nrhs", "Two inputs required.");\n'... ' }\n'... ' \n'... ' /* 获取输入矩阵尺寸 */\n'... ' m = mxGetM(prhs[0]);\n'... ' n = mxGetN(prhs[0]);\n'... ' p = mxGetN(prhs[1]);\n'... ' \n'... ' /* 检查矩阵尺寸兼容性 */\n'... ' if (n != mxGetM(prhs[1])) {\n'... ' mexErrMsgIdAndTxt("MyToolbox:matrix_multiply:incompatible", "Matrix dimensions incompatible.");\n'... ' }\n'... ' \n'... ' /* 获取输入数据指针 */\n'... ' A = mxGetPr(prhs[0]);\n'... ' B = mxGetPr(prhs[1]);\n'... ' \n'... ' /* 创建输出矩阵 */\n'... ' plhs[0] = mxCreateDoubleMatrix(m, p, mxREAL);\n'... ' C = mxGetPr(plhs[0]);\n'... ' \n'... ' /* 矩阵乘法 */\n'... ' for (i = 0; i < m; i++) {\n'... ' for (j = 0; j < p; j++) {\n'... ' C[i + j*m] = 0;\n'... ' for (k = 0; k < n; k++) {\n'... ' C[i + j*m] += A[i + k*m] * B[k + j*n];\n'... ' }\n'... ' }\n'... ' }\n'... '}\n' ]);
% 写入C文件 fid = fopen('matrix_multiply.c', 'w'); fprintf(fid, '%s', c_code); fclose(fid);
% 编译MEX文件 try mex matrix_multiply.c; fprintf('MEX文件编译成功\n');
% 测试MEX函数 A = randn(100, 50); B = randn(50, 80);
% 使用MEX函数 tic; C_mex = matrix_multiply(A, B); mex_time = toc;
% 使用MATLAB内置函数 tic; C_matlab = A * B; matlab_time = toc;
% 比较结果 fprintf('MEX函数时间: %.6f 秒\n', mex_time); fprintf('MATLAB内置函数时间: %.6f 秒\n', matlab_time); fprintf('结果误差: %.2e\n', norm(C_mex - C_matlab, 'fro') / norm(C_matlab, 'fro'));
catch ME fprintf('MEX编译失败: %s\n', ME.message); endend
% 运行MEX示例create_mex_example();16.7 高级绘图技术
跳转到“16.7 高级绘图技术”16.7.1 动画制作
跳转到“16.7.1 动画制作”% 动画示例function create_animations() % 示例1:简单动画 figure('Position', [100, 100, 800, 600]);
% 准备数据 t = linspace(0, 4*pi, 100); x = cos(t); y = sin(t);
% 创建动画 h = plot(x(1), y(1), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r'); axis equal; axis([-1.5, 1.5, -1.5, 1.5]); grid on; title('圆周运动动画');
% 添加轨迹 hold on; trail = plot(x(1), y(1), 'b-', 'LineWidth', 1);
for i = 1:length(t) % 更新点位置 set(h, 'XData', x(i), 'YData', y(i));
% 更新轨迹 set(trail, 'XData', x(1:i), 'YData', y(1:i));
% 更新标题 title(sprintf('圆周运动动画 - 时间: %.2f', t(i)));
drawnow; pause(0.05); end
% 示例2:3D动画 figure('Position', [100, 100, 800, 600]);
% 创建3D螺旋 t = linspace(0, 6*pi, 200); x = cos(t); y = sin(t); z = t;
h3d = plot3(x(1), y(1), z(1), 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r'); axis equal; axis([-1.5, 1.5, -1.5, 1.5, 0, 6*pi]); grid on; title('3D螺旋动画'); xlabel('X'); ylabel('Y'); zlabel('Z');
hold on; trail3d = plot3(x(1), y(1), z(1), 'b-', 'LineWidth', 2);
for i = 1:length(t) set(h3d, 'XData', x(i), 'YData', y(i), 'ZData', z(i)); set(trail3d, 'XData', x(1:i), 'YData', y(1:i), 'ZData', z(1:i));
% 旋转视角 view(30 + i*2, 30);
drawnow; pause(0.02); endend
% 创建GIF动画function create_gif_animation() % 准备数据 x = linspace(-2*pi, 2*pi, 100);
figure('Position', [100, 100, 800, 600]); filename = 'wave_animation.gif';
for n = 1:50 % 创建波动 y = sin(x + n*0.2);
plot(x, y, 'b-', 'LineWidth', 2); ylim([-1.5, 1.5]); title(sprintf('正弦波动画 - 帧 %d', n)); xlabel('x'); ylabel('sin(x + t)'); grid on;
drawnow;
% 保存为GIF frame = getframe(gcf); im = frame2im(frame); [imind, cm] = rgb2ind(im, 256);
if n == 1 imwrite(imind, cm, filename, 'gif', 'Loopcount', inf, 'DelayTime', 0.1); else imwrite(imind, cm, filename, 'gif', 'WriteMode', 'append', 'DelayTime', 0.1); end end
fprintf('GIF动画保存为: %s\n', filename);end
% 运行动画示例create_animations();create_gif_animation();16.7.2 交互式图形
跳转到“16.7.2 交互式图形”% 交互式绘图示例function interactive_plotting() % 创建交互式绘图界面 fig = figure('Position', [100, 100, 1000, 700], 'Name', '交互式函数绘图器');
% 创建控件 amplitude_slider = uicontrol('Style', 'slider', 'Position', [50, 50, 200, 20], ... 'Min', 0.1, 'Max', 5, 'Value', 1, 'Callback', @update_plot);
frequency_slider = uicontrol('Style', 'slider', 'Position', [50, 80, 200, 20], ... 'Min', 0.1, 'Max', 10, 'Value', 1, 'Callback', @update_plot);
phase_slider = uicontrol('Style', 'slider', 'Position', [50, 110, 200, 20], ... 'Min', -pi, 'Max', pi, 'Value', 0, 'Callback', @update_plot);
% 创建标签 uicontrol('Style', 'text', 'Position', [260, 45, 80, 20], 'String', '振幅'); uicontrol('Style', 'text', 'Position', [260, 75, 80, 20], 'String', '频率'); uicontrol('Style', 'text', 'Position', [260, 105, 80, 20], 'String', '相位');
% 创建函数选择按钮 function_group = uibuttongroup('Position', [0.65, 0.05, 0.3, 0.15]); sin_button = uicontrol(function_group, 'Style', 'radiobutton', ... 'Position', [10, 60, 100, 20], 'String', '正弦函数', 'Callback', @update_plot); cos_button = uicontrol(function_group, 'Style', 'radiobutton', ... 'Position', [10, 35, 100, 20], 'String', '余弦函数', 'Callback', @update_plot); tan_button = uicontrol(function_group, 'Style', 'radiobutton', ... 'Position', [10, 10, 100, 20], 'String', '正切函数', 'Callback', @update_plot);
% 设置默认选择 set(sin_button, 'Value', 1);
% 创建绘图区域 ax = axes('Position', [0.1, 0.3, 0.8, 0.6]);
% 初始化绘图 x = linspace(-2*pi, 2*pi, 1000); line_handle = plot(ax, x, sin(x), 'b-', 'LineWidth', 2); grid(ax, 'on'); xlabel(ax, 'x'); ylabel(ax, 'y'); title(ax, 'y = sin(x)');
% 回调函数 function update_plot(~, ~) % 获取参数值 amp = get(amplitude_slider, 'Value'); freq = get(frequency_slider, 'Value'); phase = get(phase_slider, 'Value');
% 确定函数类型 if get(sin_button, 'Value') y = amp * sin(freq * x + phase); func_name = 'sin'; elseif get(cos_button, 'Value') y = amp * cos(freq * x + phase); func_name = 'cos'; else y = amp * tan(freq * x + phase); func_name = 'tan'; % 限制tan函数的显示范围 y(abs(y) > 10) = NaN; end
% 更新绘图 set(line_handle, 'YData', y); title(ax, sprintf('y = %.2f * %s(%.2f * x + %.2f)', amp, func_name, freq, phase));
% 自动调整坐标轴 if strcmp(func_name, 'tan') ylim(ax, [-10, 10]); else ylim(ax, [-amp*1.2, amp*1.2]); end endend
% 互动式数据探索器function data_explorer() % 创建示例数据 load('fisheriris'); % 载入鸢尾花数据集
fig = figure('Position', [100, 100, 1200, 800], 'Name', '数据探索器');
% 创建下拉菜单选择变量 var_menu = uicontrol('Style', 'popup', 'Position', [50, 750, 150, 30], ... 'String', {'萼片长度', '萼片宽度', '花瓣长度', '花瓣宽度'}, ... 'Callback', @update_visualization);
plot_type_menu = uicontrol('Style', 'popup', 'Position', [220, 750, 150, 30], ... 'String', {'散点图', '直方图', '箱线图', '小提琴图'}, ... 'Callback', @update_visualization);
% 创建标签 uicontrol('Style', 'text', 'Position', [50, 780, 150, 20], 'String', '选择变量:'); uicontrol('Style', 'text', 'Position', [220, 780, 150, 20], 'String', '选择图表类型:');
% 创建绘图区域 ax1 = axes('Position', [0.1, 0.4, 0.35, 0.35]); ax2 = axes('Position', [0.55, 0.4, 0.35, 0.35]); ax3 = axes('Position', [0.1, 0.05, 0.8, 0.25]);
% 初始化显示 update_visualization();
function update_visualization(~, ~) var_idx = get(var_menu, 'Value'); plot_type = get(plot_type_menu, 'Value');
data = meas(:, var_idx); var_names = {'萼片长度', '萼片宽度', '花瓣长度', '花瓣宽度'};
% 清除之前的图形 cla(ax1); cla(ax2); cla(ax3);
switch plot_type case 1 % 散点图 % 散点图矩阵 for i = 1:4 for j = 1:4 subplot(4, 4, (i-1)*4 + j, 'Parent', fig); if i == j histogram(meas(:, i)); else gscatter(meas(:, j), meas(:, i), species); end end end
case 2 % 直方图 histogram(ax1, data, 20); title(ax1, ['直方图 - ' var_names{var_idx}]); xlabel(ax1, var_names{var_idx}); ylabel(ax1, '频次');
% 按种类分组的直方图 setosa_data = data(strcmp(species, 'setosa')); versicolor_data = data(strcmp(species, 'versicolor')); virginica_data = data(strcmp(species, 'virginica'));
hold(ax2, 'on'); histogram(ax2, setosa_data, 'FaceAlpha', 0.7, 'DisplayName', 'Setosa'); histogram(ax2, versicolor_data, 'FaceAlpha', 0.7, 'DisplayName', 'Versicolor'); histogram(ax2, virginica_data, 'FaceAlpha', 0.7, 'DisplayName', 'Virginica'); legend(ax2); title(ax2, ['按种类分组 - ' var_names{var_idx}]);
case 3 % 箱线图 boxplot(ax1, data, species); title(ax1, ['箱线图 - ' var_names{var_idx}]); ylabel(ax1, var_names{var_idx});
% 显示统计信息 stats_text = sprintf('统计信息:\n均值: %.2f\n中位数: %.2f\n标准差: %.2f\n最小值: %.2f\n最大值: %.2f', ... mean(data), median(data), std(data), min(data), max(data)); text(ax2, 0.1, 0.5, stats_text, 'Units', 'normalized', 'FontSize', 12); set(ax2, 'XTick', [], 'YTick', []); title(ax2, '描述性统计'); end
% 在底部显示相关性分析 correlation_matrix = corrcoef(meas); imagesc(ax3, correlation_matrix); colorbar(ax3); set(ax3, 'XTick', 1:4, 'YTick', 1:4, 'XTickLabel', var_names, 'YTickLabel', var_names); title(ax3, '变量间相关性矩阵'); colormap(ax3, 'cool'); endend16.7.3 App Designer
跳转到“16.7.3 App Designer”App Designer是MATLAB现代化的图形界面开发工具,类似于Python的Tkinter或Qt,但更加直观。
% 使用App Designer创建计算器应用% 注意:这需要在App Designer环境中创建,这里展示核心逻辑
classdef CalculatorApp < matlab.apps.AppBase % App Designer创建的计算器应用
properties (Access = public) UIFigure matlab.ui.Figure DisplayField matlab.ui.control.EditField ButtonGrid matlab.ui.container.GridLayout CurrentValue double = 0 PreviousValue double = 0 Operation char = '' NewInput logical = true end
methods (Access = private)
function results = calculateResult(app) switch app.Operation case '+' results = app.PreviousValue + app.CurrentValue; case '-' results = app.PreviousValue - app.CurrentValue; case '*' results = app.PreviousValue * app.CurrentValue; case '/' if app.CurrentValue ~= 0 results = app.PreviousValue / app.CurrentValue; else results = NaN; uialert(app.UIFigure, '除数不能为零!', '错误'); end case '^' results = app.PreviousValue ^ app.CurrentValue; otherwise results = app.CurrentValue; end end
function numberButtonPushed(app, event) button = event.Source; number = str2double(button.Text);
if app.NewInput app.DisplayField.Value = button.Text; app.NewInput = false; else app.DisplayField.Value = [app.DisplayField.Value button.Text]; end
app.CurrentValue = str2double(app.DisplayField.Value); end
function operationButtonPushed(app, event) button = event.Source;
if ~isempty(app.Operation) && ~app.NewInput result = app.calculateResult(); app.DisplayField.Value = num2str(result); app.CurrentValue = result; end
app.PreviousValue = app.CurrentValue; app.Operation = button.Text; app.NewInput = true; end
function equalsButtonPushed(app, event) if ~isempty(app.Operation) result = app.calculateResult(); app.DisplayField.Value = num2str(result); app.CurrentValue = result; app.Operation = ''; app.NewInput = true; end end
function clearButtonPushed(app, event) app.DisplayField.Value = '0'; app.CurrentValue = 0; app.PreviousValue = 0; app.Operation = ''; app.NewInput = true; end end
methods (Access = private)
function createComponents(app) % 创建UIFigure和组件 app.UIFigure = uifigure('Visible', 'off'); app.UIFigure.Position = [100 100 300 400]; app.UIFigure.Name = 'MATLAB 计算器';
% 创建显示屏 app.DisplayField = uieditfield(app.UIFigure, 'text'); app.DisplayField.Position = [20 340 260 40]; app.DisplayField.Value = '0'; app.DisplayField.FontSize = 16; app.DisplayField.HorizontalAlignment = 'right'; app.DisplayField.Editable = 'off';
% 创建按钮网格 app.ButtonGrid = uigridlayout(app.UIFigure); app.ButtonGrid.Position = [20 20 260 300]; app.ButtonGrid.ColumnWidth = {'1x', '1x', '1x', '1x'}; app.ButtonGrid.RowHeight = {'1x', '1x', '1x', '1x', '1x'};
% 创建按钮 buttons = { 'C', '±', '%', '÷'; '7', '8', '9', '×'; '4', '5', '6', '-'; '1', '2', '3', '+'; '0', '.', '=', '^' };
for row = 1:5 for col = 1:4 btn = uibutton(app.ButtonGrid, 'push'); btn.Layout.Row = row; btn.Layout.Column = col; btn.Text = buttons{row, col}; btn.FontSize = 14;
% 设置回调函数 if ismember(btn.Text, {'0','1','2','3','4','5','6','7','8','9','.'}) btn.ButtonPushedFcn = createCallbackFcn(app, @numberButtonPushed, true); elseif ismember(btn.Text, {'+','-','×','÷','^'}) btn.ButtonPushedFcn = createCallbackFcn(app, @operationButtonPushed, true); elseif strcmp(btn.Text, '=') btn.ButtonPushedFcn = createCallbackFcn(app, @equalsButtonPushed, true); elseif strcmp(btn.Text, 'C') btn.ButtonPushedFcn = createCallbackFcn(app, @clearButtonPushed, true); end end end end end
methods (Access = public)
function app = CalculatorApp % 构造函数 createComponents(app); registerApp(app, app.UIFigure);
if nargout == 0 clear app end end
function delete(app) % 析构函数 delete(app.UIFigure); end endend16.8 与其他语言对比
跳转到“16.8 与其他语言对比”16.8.1 MATLAB vs Python
跳转到“16.8.1 MATLAB vs Python”| 特性 | MATLAB | Python |
|---|---|---|
| 矩阵运算 | 原生支持,语法简洁 | 需要NumPy,功能强大 |
| 绘图 | 内置强大绘图功能 | Matplotlib/Plotly等 |
| 社区 | 学术界广泛使用 | 开源社区庞大 |
| 成本 | 商业软件,需授权 | 免费开源 |
| 学习曲线 | 工程背景易上手 | 编程背景易上手 |
% MATLAB矩阵运算A = [1 2; 3 4];B = [5 6; 7 8];C = A * B; % 矩阵乘法D = A .* B; % 元素乘法# Python等效代码import numpy as npA = np.array([[1, 2], [3, 4]])B = np.array([[5, 6], [7, 8]])C = A @ B # 矩阵乘法D = A * B # 元素乘法16.8.2 MATLAB vs C++
跳转到“16.8.2 MATLAB vs C++”| 特性 | MATLAB | C++ |
|---|---|---|
| 开发速度 | 快速原型开发 | 需要更多代码 |
| 执行速度 | 解释执行,较慢 | 编译执行,很快 |
| 内存管理 | 自动管理 | 手动管理 |
| 数值计算 | 内置优化算法 | 需要第三方库 |
| 可移植性 | 需要MATLAB环境 | 编译后独立运行 |
% MATLAB快速实现FFTx = randn(1024, 1);X = fft(x);plot(abs(X));// C++需要更多代码实现相同功能#include <fftw3.h>#include <vector>#include <complex>
std::vector<std::complex<double>> computeFFT(const std::vector<double>& input) { // 需要大量代码实现FFT和绘图 // ...}16.9 最佳实践总结
跳转到“16.9 最佳实践总结”16.9.1 代码组织
跳转到“16.9.1 代码组织”% 良好的代码组织示例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); endend
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); endend16.9.2 性能优化技巧
跳转到“16.9.2 性能优化技巧”% 性能优化示例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; % 清理临时数据 endend16.9.3 调试技巧
跳转到“16.9.3 调试技巧”% 调试工具和技巧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));end16.10 常见错误及解决方案
跳转到“16.10 常见错误及解决方案”16.10.1 索引错误
跳转到“16.10.1 索引错误”% 常见索引错误及解决方案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 endend16.10.2 数据类型错误
跳转到“16.10.2 数据类型错误”% 数据类型相关错误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 endend16.11 项目实战综合案例
跳转到“16.11 项目实战综合案例”16.11.1 股票数据分析系统
跳转到“16.11.1 股票数据分析系统”% 股票数据分析系统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 endend
% 使用示例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来源:CSDN 原文,首次发布于 2025-07-05。