1. MATLAB简介与环境
1.1 什么是MATLAB
MATLAB(Matrix Laboratory)是一个高性能的数值计算环境和编程语言,专为工程计算、数据分析和算法开发设计。
1.2 与Python/C++的对比
特性
Python
C/C++
MATLAB
类型
解释型
编译型
解释型
主要用途
通用编程
系统编程
数值计算
矩阵运算
需要NumPy
需要库
内置支持
学习曲线
平缓
陡峭
中等
执行速度
中等
最快
快(矩阵运算)
1.3 MATLAB环境
命令窗口(Command Window) : 交互式执行命令
编辑器(Editor) : 编写和编辑脚本、函数
工作区(Workspace) : 查看变量
命令历史(Command History) : 查看历史命令
当前文件夹(Current Folder) : 文件管理
1.4 基本操作命令
clc
clear
clear var
close all
who
whos
pwd
cd
ls
2. 基本语法与数据类型
2.1 语法规则
这是多行注释
可以写很多行
a = 5 ;
b = 3
long_variable_name = 1 + 2 + 3 + ...
4 + 5 + 6 ;
2.2 变量命名规则
var1 = 10 ;
my_variable = 20 ;
MyVariable = 30 ;
variable_2023 = 40 ;
2.3 数据类型详解
2.3.1 数值类型
a = 3.14159 ;
b = 1.23e-4 ;
c = 1.23e4 ;
int8_var = int8 ( 127 ) ;
uint8_var = uint8 ( 255 ) ;
int16_var = int16 ( 32767 ) ;
uint16_var = uint16 ( 65535 ) ;
int32_var = int32 ( 2147483647 ) ;
uint32_var = uint32 ( 4294967295 ) ;
int64_var = int64 ( 9223372036854775807 ) ;
single_var = single ( 3.14159 ) ;
complex_var = 3 + 4i ;
complex_var2 = complex ( 3 , 4 ) ;
2.3.2 逻辑类型
bool_true = true;
bool_false = false;
result = ( 5 > 3 ) ;
result2 = ( 2 == 3 ) ;
logical_array = [ true, false, true] ;
2.3.3 字符和字符串
char_var = 'Hello' ;
char_array = [ 'Hello' ; 'World' ] ;
str_var = "Hello";
str_array = [ "Hello", "World", "MATLAB"] ;
char_example = 'Hello' ;
string_example = "Hello";
2.4 类型转换
a = 3.14 ;
b = int32 ( a) ;
c = single ( a) ;
d = char ( 65 ) ;
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.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 使用函数创建
zeros_matrix = zeros ( 3 , 4 ) ;
ones_matrix = ones ( 2 , 5 ) ;
eye_matrix = eye ( 4 ) ;
diag_matrix = diag ( [ 1 , 2 , 3 , 4 ] ) ;
rand_matrix = rand ( 3 , 3 ) ;
randn_matrix = randn ( 2 , 4 ) ;
randi_matrix = randi ( 10 , 3 , 3 ) ;
randi_matrix2 = randi ( [ 5 , 15 ] , 2 , 3 ) ;
3.1.3 序列创建
seq1 = 1 : 5 ;
seq2 = 1 : 2 : 10 ;
seq3 = 10 : - 1 : 1 ;
linspace_seq = linspace ( 0 , 10 , 5 ) ;
logspace_seq = logspace ( 1 , 3 , 5 ) ;
repmat_array = repmat ( [ 1 , 2 ] , 3 , 2 ) ;
3.2 数组索引与切片
3.2.1 基本索引(注意:MATLAB索引从1开始!)
A = [ 1 , 2 , 3 ; 4 , 5 , 6 ; 7 , 8 , 9 ] ;
element = A ( 2 , 3 ) ;
element2 = A ( 1 , 1 ) ;
linear_element = A ( 5 ) ;
linear_element2 = A ( end ) ;
last_element = A ( end , end ) ;
second_last = A ( end - 1 , end ) ;
3.2.2 切片操作
A = [ 1 , 2 , 3 , 4 ; 5 , 6 , 7 , 8 ; 9 , 10 , 11 , 12 ] ;
first_row = A ( 1 , : ) ;
last_row = A ( end , : ) ;
first_col = A ( : , 1 ) ;
last_col = A ( : , end ) ;
sub_matrix = A ( 1 : 2 , 2 : 3 ) ;
sub_matrix2 = A ( [ 1 , 3 ] , [ 2 , 4 ] ) ;
all_elements = A ( : ) ;
3.2.3 逻辑索引
A = [ 1 , - 2 , 3 ; - 4 , 5 , - 6 ; 7 , - 8 , 9 ] ;
positive_mask = A > 0 ;
positive_elements = A ( A > 0 ) ;
condition = ( A > 0 ) & ( A < 8 ) ;
selected = A ( condition) ;
A ( A < 0 ) = 0 ;
3.3 数组操作
3.3.1 数组拼接
A = [ 1 , 2 ; 3 , 4 ] ;
B = [ 5 , 6 ; 7 , 8 ] ;
C_horizontal = [ A, B] ;
C_horizontal2 = horzcat ( A, B) ;
C_vertical = [ A; B] ;
C_vertical2 = vertcat ( A, B) ;
C_3d = cat ( 3 , A, B) ;
3.3.2 数组重塑
A = [ 1 , 2 , 3 , 4 , 5 , 6 ] ;
B = reshape ( A, 2 , 3 ) ;
C = reshape ( A, 3 , 2 ) ;
A_matrix = [ 1 , 2 , 3 ; 4 , 5 , 6 ] ;
A_transpose = A_matrix' ;
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 数组排序
vec = [ 3 , 1 , 4 , 1 , 5 , 9 ] ;
sorted_vec = sort ( vec) ;
sorted_desc = sort ( vec, 'descend' ) ;
[ sorted_vec, indices] = sort ( vec) ;
matrix = [ 3 , 1 , 4 ; 1 , 5 , 9 ; 2 , 6 , 5 ] ;
sorted_matrix = sort ( matrix) ;
sorted_matrix2 = sort ( matrix, 2 ) ;
4. 运算符详解
4.1 算术运算符
4.1.1 标量运算
a = 10 ; b = 3 ;
addition = a + b;
subtraction = a - b;
multiplication = a * b;
division = a / b;
power = a ^ b;
modulo = mod ( a, b) ;
4.1.2 矩阵运算
A = [ 1 , 2 ; 3 , 4 ] ;
B = [ 5 , 6 ; 7 , 8 ] ;
scalar = 2 ;
C = A + B;
D = A - B;
E = A * B;
F = A * scalar;
G = A / B;
H = A \ B;
I = A ^ 2 ;
4.1.3 逐元素运算(重要!)
A = [ 1 , 2 ; 3 , 4 ] ;
B = [ 5 , 6 ; 7 , 8 ] ;
C = A .* B;
D = A ./ B;
E = A .^ 2 ;
F = A .^ B;
G = sqrt ( A) ;
H = sin ( A) ;
I = exp ( A) ;
4.2 比较运算符
a = 5 ; b = 3 ;
A = [ 1 , 2 , 3 ; 4 , 5 , 6 ] ;
B = [ 1 , 0 , 4 ; 4 , 5 , 0 ] ;
result1 = a > b;
result2 = a == b;
result3 = a ~= b;
result4 = a <= b;
C = A > B;
D = A == B;
E = A ~= B;
is_equal = isequal ( A, B) ;
is_close = all ( abs ( A- B) < 1e-10 , 'all' ) ;
4.3 逻辑运算符
a = true; b = false;
result1 = a && b;
result2 = a || b;
result3 = ~ a;
A = [ true, false; true, true] ;
B = [ false, true; true, false] ;
C = A & B;
D = A | B;
E = ~ A;
result_any = any ( A) ;
result_all = all ( A) ;
result_any_all = any ( A, 'all' ) ;
result_all_all = all ( A, 'all' ) ;
4.4 位运算符
a = 5 ;
b = 3 ;
bit_and = bitand ( a, b) ;
bit_or = bitor ( a, b) ;
bit_xor = bitxor ( a, b) ;
bit_not = bitcmp ( a, 8 ) ;
bit_shift_left = bitshift ( a, 2 ) ;
bit_shift_right = bitshift ( a, - 1 ) ;
5. 控制结构
5.1 条件语句
5.1.1 if-else语句
x = 10 ;
if x > 5
disp ( 'x大于5' ) ;
end
x = 3 ;
if x > 5
disp ( 'x大于5' ) ;
else
disp ( 'x不大于5' ) ;
end
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语句
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 }
day_name = '周末' ;
otherwise
day_name = '无效日期' ;
end
fprintf ( '今天是%s\n' , day_name) ;
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循环
for i = 1 : 5
fprintf ( 'i = %d\n' , i ) ;
end
for i = 1 : 2 : 10
fprintf ( 'i = %d\n' , i ) ;
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循环
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 ) ;
counter = 0 ;
while true
counter = counter + 1 ;
if counter > 10
break ;
end
fprintf ( '计数器: %d\n' , counter) ;
end
5.2.3 循环控制语句
for i = 1 : 10
if i == 5
break ;
end
fprintf ( 'i = %d\n' , i ) ;
end
for i = 1 : 10
if mod ( i , 2 ) == 0
continue ;
end
fprintf ( '奇数: %d\n' , i ) ;
end
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 异常处理
try
a = 10 ;
b = 0 ;
result = a / b;
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
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 函数定义
function result = square ( 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 函数调用
x = 5 ;
y = square ( x) ;
result = add_numbers ( 1 , 2 , 3 ) ;
[ s, d, p] = calculate ( 10 , 5 ) ;
s_only = calculate ( 10 , 5 ) ;
total = sum_all ( 1 , 2 , 3 , 4 , 5 ) ;
6.2 高级函数特性
6.2.1 默认参数和参数检查
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 嵌套函数和子函数
function main_function ( )
x = 10 ;
y = 5 ;
result = nested_calculation ( ) ;
fprintf ( '结果: %d\n' , result) ;
function output = nested_calculation ( )
output = x + y;
end
end
function main_with_subfunctions ( )
data = [ 1 , 2 , 3 , 4 , 5 ] ;
processed = process_data ( data) ;
display_results ( processed) ;
end
function result = process_data ( data)
result = data .* 2 + 1 ;
end
function display_results ( data)
fprintf ( '处理后的数据: ' ) ;
fprintf ( '%d ' , data) ;
fprintf ( '\n' ) ;
end
6.2.3 匿名函数和函数句柄
square_func = @ ( x) x.^ 2 ;
result = square_func ( 5 ) ;
add_func = @ ( a, b) a + b;
result = add_func ( 3 , 4 ) ;
complex_func = @ ( x, y) sqrt ( x.^ 2 + y.^ 2 ) ;
result = complex_func ( 3 , 4 ) ;
my_sin = @ sin;
result = my_sin ( pi / 2 ) ;
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 递归函数
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
7. 数据输入输出
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 ( '您选择了否' ) ;
end
7.2 文件读写
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) ;
end
end
fclose ( fileID) ;
content = fileread ( filename) ;
disp ( content) ;
7.2.2 CSV文件操作
data = [ 1 , 2 , 3 ; 4 , 5 , 6 ; 7 , 8 , 9 ] ;
headers = { 'A' , 'B' , 'C' } ;
writematrix ( data, 'data.csv' ) ;
T = table ( data ( : , 1 ) , data ( : , 2 ) , data ( : , 3 ) , 'VariableNames' , headers) ;
writetable ( T, 'data_with_headers.csv' ) ;
loaded_data = readmatrix ( 'data.csv' ) ;
loaded_table = readtable ( 'data_with_headers.csv' ) ;
fprintf ( '数据维度: %dx%d\n' , size ( loaded_data) ) ;
fprintf ( '数据和: %.2f\n' , sum ( loaded_data, 'all' ) ) ;
7.2.3 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) ;
writetable ( T, 'example.xlsx' , 'Sheet' , 'Sheet1' ) ;
excel_data = readtable ( 'example.xlsx' ) ;
excel_matrix = readmatrix ( 'example.xlsx' ) ;
range_data = readmatrix ( 'example.xlsx' , 'Range' , 'A1:C5' ) ;
7.3 MAT文件操作
a = [ 1 , 2 , 3 ] ;
b = 'Hello' ;
c = struct ( 'name' , 'Alice' , 'age' , 25 ) ;
save ( 'data.mat' ) ;
save ( 'specific_data.mat' , 'a' , 'b' ) ;
clear;
load ( 'data.mat' ) ;
load ( 'data.mat' , 'a' ) ;
file_info = whos ( '-file' , 'data.mat' ) ;
disp ( file_info) ;
8. 绘图与可视化
8.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 图形样式设置
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 子图
figure;
x = 0 : 0.1 : 2 * pi ;
subplot ( 2 , 2 , 1 ) ;
plot ( x, sin ( x) ) ;
title ( 'sin(x)' ) ;
grid on;
subplot ( 2 , 2 , 2 ) ;
plot ( x, cos ( x) ) ;
title ( 'cos(x)' ) ;
grid on;
subplot ( 2 , 2 , 3 ) ;
plot ( x, tan ( x) ) ;
title ( 'tan(x)' ) ;
ylim ( [ - 5 , 5 ] ) ;
grid on;
subplot ( 2 , 2 , 4 ) ;
plot ( x, exp ( - x) ) ;
title ( 'exp(-x)' ) ;
grid on;
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 特殊图形
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.1 字符串基础
char_array = 'Hello World' ;
string_array = "Hello World";
len1 = length ( char_array) ;
len2 = strlength ( string_array) ;
combined_char = [ char_array, ' MATLAB' ] ;
combined_char2 = strcat ( char_array, ' MATLAB' ) ;
combined_string = string_array + " MATLAB";
combined_string2 = strcat ( string_array, " MATLAB") ;
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") ;
sentence = "apple, banana, cherry";
parts = split ( sentence, ", ") ;
upper_text = upper ( "hello world") ;
lower_text = lower ( "HELLO WORLD") ;
title_text = title ( "hello world") ;
9.3 正则表达式
text = "My phone number is 123 - 456 - 7890 ";
pattern = '\d{3}-\d{3}-\d{4}' ;
match = regexp ( text, pattern, 'match' ) ;
text = "Price: $25.99 , Tax: $2.60 ";
numbers = regexp ( text, '\d+\.\d+' , 'match' ) ;
email = "contact@ example. com";
domain_pattern = '@\w+\.\w+' ;
new_email = regexprep ( email, domain_pattern, '@newdomain.com' ) ;
9.4 字符串格式化
name = "Alice";
age = 25 ;
formatted = sprintf ( "姓名:
formatted_modern = name + " is " + age + " years old";
pi_formatted = sprintf ( "π ≈
current_date = datetime ( 'now' ) ;
date_string = string ( current_date, 'yyyy-MM-dd HH:mm:ss' ) ;
10. 结构体与元胞数组
10.1 结构体
10.1.1 结构体创建和访问
student. name = 'Alice' ;
student. age = 20 ;
student. scores = [ 85 , 92 , 78 ] ;
student2 = struct ( 'name' , 'Bob' , 'age' , 21 , 'scores' , [ 90 , 88 , 95 ] ) ;
fprintf ( '学生姓名: %s\n' , student. name) ;
fprintf ( '平均分: %.2f\n' , mean ( student. scores) ) ;
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 嵌套结构体
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) ;
end
10.2 元胞数组
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 元胞数组操作
first_element = cell_array{ 1 } ;
second_element = cell_array{ 2 } ;
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 ) ) ;
end
10.2.3 元胞数组的高级操作
numbers_cell = { [ 1 , 2 , 3 ] , [ 4 , 5 ] , [ 6 , 7 , 8 , 9 ] } ;
lengths = cellfun ( @ length, numbers_cell) ;
means = cellfun ( @ mean, numbers_cell) ;
names = { 'Alice' , 'Bob' , 'Charlie' } ;
name_lengths = cellfun ( @ length, names) ;
upper_names = cellfun ( @ upper, names, 'UniformOutput' , false) ;
[ sorted_names, indices] = sort ( names) ;
11. 文件操作
11.1 文件系统操作
current_dir = pwd;
cd ( '/path/to/directory' ) ;
cd ( current_dir) ;
file_info = dir ( '*.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' ) ;
end
rmdir ( 'temp_folder' ) ;
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 批量文件处理
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) ;
end
12. 调试与错误处理
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
end
end
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
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 向量化操作
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 内存管理
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 性能分析
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
14. 工具箱简介
14.1 常用工具箱
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 ) ) ;
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(图像处理工具箱)
img = imread ( 'cameraman.tif' ) ;
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(统计和机器学习工具箱)
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] ;
[ 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;
end
scatter ( centers ( : , 1 ) , centers ( : , 2 ) , 100 , 'k' , 'x' , 'LineWidth' , 2 ) ;
title ( 'K-means聚类结果' ) ;
legend ( '聚类1' , '聚类2' , '聚类3' , '聚类中心' ) ;
14.1.4 Optimization Toolbox(优化工具箱)
objective = @ ( x) x ( 1 ) ^ 2 + x ( 2 ) ^ 2 + x ( 1 ) * x ( 2 ) ;
x0 = [ 1 , 1 ] ;
A = [ 1 , 1 ] ;
b = 2 ;
Aeq = [ 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(控制系统工具箱)
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 工具箱函数查找
ver
help signal
help images
help stats
lookfor filter
15. 实战项目
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 ) ) ;
end
end
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:信号处理应用
fs = 44100 ;
duration = 3 ;
t = 0 : 1 / fs: duration- 1 / fs;
freq1 = 440 ;
freq2 = 880 ;
freq3 = 1320 ;
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) ) ;
[ b_low, a_low] = butter ( 6 , 600 / ( fs/ 2 ) , 'low' ) ;
low_freq = filter ( b_low, a_low, noisy_signal) ;
[ b_band, a_band] = butter ( 6 , [ 600 , 1000 ] / ( fs/ 2 ) , 'bandpass' ) ;
mid_freq = filter ( b_band, a_band, noisy_signal) ;
[ 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 ( '幅度' ) ;
15.3 项目3:图像处理应用
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 ) ;
end
title ( 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:数值计算应用
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) ;
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 ] ) ;
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' ) ;
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 索引错误
A = [ 1 , 2 , 3 ] ;
try
value = A ( 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 维度不匹配
A = [ 1 , 2 , 3 ] ;
B = [ 4 ; 5 ; 6 ] ;
try
C = A + B;
catch ME
fprintf ( '错误: %s\n' , ME. message) ;
end
C1 = A + B' ;
C2 = A + B' ;
C3 = A + reshape ( B, 1 , 3 ) ;
16.1.3 数据类型问题
a = uint8 ( 255 ) ;
b = uint8 ( 10 ) ;
c = a + b;
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) ;
16.2 性能问题诊断
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 代码剖析
function performance_comparison ( )
n = 1000 ;
tic;
result1 = zeros ( n, 1 ) ;
for i = 1 : n
result1 ( i ) = sin ( i ) * cos ( i ) ;
end
time1 = toc;
tic;
x = ( 1 : n) ' ;
result2 = sin ( x) .* cos ( x) ;
time2 = toc;
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 断点和单步执行
function result = debug_example ( x)
y = x.^ 2 ;
if any ( y > 100 )
disp ( '发现大值' ) ;
end
z = sin ( y) ;
result = sum ( z) ;
end
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' ) ;
end
end
robust_calculation ( [ 1 , 2 , 3 , NaN , 5 ] ) ;
robust_calculation ( 'invalid' ) ;
16.4 最佳实践总结
16.4.1 编程风格
function [ mean_val, std_val, processed_data] = process_data ( input_data, options)
%
%
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 代码组织
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 ( ) ;
end
end
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) ;
end
end
16.5 高级技巧和技术
16.5.1 面向对象编程
classdef DataAnalyzer < handle
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
end
end
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 并行计算
function parallel_computing_demo ( )
if ~ license ( 'test' , 'Distrib_Computing_Toolbox' )
warning ( '未安装并行计算工具箱' ) ;
return ;
end
if isempty ( gcp ( 'nocreate' ) )
parpool ( 'local' , 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计算
function gpu_computing_demo ( )
if ~ canUseGPU ( )
warning ( 'GPU不可用或未安装Parallel Computing Toolbox' ) ;
return ;
end
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) ;
tic;
C_cpu = A_cpu * B_cpu;
cpu_time = toc;
A_gpu = gpuArray ( A_cpu) ;
B_gpu = gpuArray ( B_cpu) ;
tic;
C_gpu = A_gpu * B_gpu;
wait ( gpu_info) ;
gpu_time = toc;
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' ) ) ;
clear A_gpu B_gpu C_gpu;
end
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) ) ;
signal_gpu = gpuArray ( signal_cpu) ;
tic;
fft_gpu = fft ( signal_gpu) ;
power_spectrum_gpu = abs ( fft_gpu) .^ 2 ;
gpu_fft_time = toc;
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
if canUseGPU ( )
gpu_computing_demo ( ) ;
gpu_signal_processing ( ) ;
end
16.6 与其他语言的接口
16.6.1 调用Python代码
function python_interface_demo ( )
try
pyenv;
fprintf ( 'Python环境已配置\n' ) ;
catch
fprintf ( 'Python环境未配置,请先配置Python\n' ) ;
return ;
end
py_list = py. list ( { 1 , 2 , 3 , 4 , 5 } ) ;
py_sum = py. sum ( py_list) ;
fprintf ( 'Python list sum: %d\n' , py_sum) ;
try
np = py. importlib. import_module ( 'numpy' ) ;
data_matlab = [ 1 , 2 , 3 ; 4 , 5 , 6 ] ;
data_numpy = np. array ( data_matlab) ;
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_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) ;
end
end
function python_ml_demo ( )
try
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 } ) ;
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) ;
end
end
python_interface_demo ( ) ;
python_ml_demo ( ) ;
16.6.2 调用C/C++代码
function create_mex_example ( )
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'
] ) ;
fid = fopen ( 'matrix_multiply.c' , 'w' ) ;
fprintf ( fid, '%s' , c_code) ;
fclose ( fid) ;
try
mex matrix_multiply. c;
fprintf ( 'MEX文件编译成功\n' ) ;
A = randn ( 100 , 50 ) ;
B = randn ( 50 , 80 ) ;
tic;
C_mex = matrix_multiply ( A, B) ;
mex_time = toc;
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) ;
end
end
create_mex_example ( ) ;
16.7 高级绘图技术
16.7.1 动画制作
function create_animations ( )
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
figure ( 'Position' , [ 100 , 100 , 800 , 600 ] ) ;
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 ) ;
end
end
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;
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 交互式图形
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' ;
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
end
end
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' ) ;
end
end
16.7.3 App Designer
App Designer是MATLAB现代化的图形界面开发工具,类似于Python的Tkinter或Qt,但更加直观。
classdef CalculatorApp < matlab. apps. AppBase
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)
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
end
end
16.8 与其他语言对比
16.8.1 MATLAB vs Python
特性
MATLAB
Python
矩阵运算
原生支持,语法简洁
需要NumPy,功能强大
绘图
内置强大绘图功能
Matplotlib/Plotly等
社区
学术界广泛使用
开源社区庞大
成本
商业软件,需授权
免费开源
学习曲线
工程背景易上手
编程背景易上手
A = [ 1 2 ; 3 4 ] ;
B = [ 5 6 ; 7 8 ] ;
C = A * B;
D = A .* B;
import numpy as np
A = 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++
特性
MATLAB
C++
开发速度
快速原型开发
需要更多代码
执行速度
解释执行,较慢
编译执行,很快
内存管理
自动管理
手动管理
数值计算
内置优化算法
需要第三方库
可移植性
需要MATLAB环境
编译后独立运行
x = randn ( 1024 , 1 ) ;
X = fft ( x) ;
plot ( abs ( X) ) ;
# include <fftw3.h>
# include <vector>
# include <complex>
std:: vector< std:: complex< double >> computeFFT ( const std:: vector< double > & input) {
}
16.9 最佳实践总结
16.9.1 代码组织
function result = data_analysis_pipeline ( data_file)
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 性能优化技巧
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 ) ;
data_single = single ( rand ( 1000 , 1000 ) ) ;
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 调试技巧
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
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 ;
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 索引错误
function index_error_solutions ( )
A = rand ( 5 , 5 ) ;
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
try
value = A ( 0 , 1 ) ;
catch
fprintf ( '错误:MATLAB索引从1开始,不是0\n' ) ;
value = A ( 1 , 1 ) ;
end
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 数据类型错误
function data_type_solutions ( )
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, ', ' ) ) ;
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 股票数据分析系统
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