从python转向matlab,记几个不一样的地方。
大不同
类属性定义不同:python类可以在定义属性的时候调用前文的变量、调用函数;matlab定义类属性不能调用前文变量及类函数。
构造函数不同:python类可以在初始化的时候自动调用构造函数;matlab的类需要专门的初始化函数,且必须明确地调用。
p = Model_Params; p = p.init()
类变量在函数中被改变,结果不同:matlab类初始化为对象后,如果在函数内部改变对象的属性值,没有返回对象,则对象的属性不会被实质性改变。
只写p.init(),输出的参数仍然为空;赋值之后,才会有真实值。
ones() 初始化方面容易犯错:Python中,初始化一个一维向量用np.ones(N)可以实现;matlab中,ones(N)是一个N维的方阵,一维向量用ones(1,N)
size()判断时候容易犯错:假设array是包含N个元素的一维向量,Python中的size(array)会得到N,而matlab中size(array) 会得到(1, N)。
返回值为两个的时候:python可直接写x, y = func();Matlab中一定要用方括号括起来,[x, y] = func()。
打印
MATLAB输出变量方法很多,主要包括以下几类。
(1)语句后面不加分号“;”,这是直接输出数值的比较简单的方法。
(2)disp(a)直接在命令窗口显示a变量,这种方法输出和第一种差不多。
(3)fprintf(‘a=%f’,a)格式控制输出,输出’a='然后再显示输出的变量。
(4)save(dir+name,‘变量名’)保存输出到某个文件中去,可以将数值保存。
print函数用于将作出的函数图像保存成指定格式的图片,紧跟在函数图像后面。
fprintf函数可以将数据按指定格式写入到文本文件中。fprintf(fid, format, data)中的fid表示由fopen函数打开的文件句柄,如果fid省略,则直接输出在屏幕上,format指定输出格式,data是要输出的数据。
fscanf可以从文件中读取数据, [a,count]=fscanf(fid, format, size), 即从fid 文件中按照格式format读出数据并按size的格式放入内存变量a中。
注释
多行注释: 选中要注释的若干语句, 编辑器菜单Text-<Comment, 或者快捷键Ctrl+R
取消注释: 选中要取消注释的语句, 编辑器菜单Text-<Uncomment, 或者快捷键Ctrl+T
数据类型
整型有int8、int16、int32等;默认类型是双精度浮点型。
Inf、-Inf表示正负无穷。NaN表示非数值。
查看数据类型:class(aaa)
当前工作空间中所有变量:whos
存储和读取
存储一个矩阵A:save A
读取一个矩阵A:A = load("A.mat")
读取矩阵之后,是结构体的形式:
>> A
ans =
包含以下字段的 struct:
A: [100×100 double]
N: 100
ans: 400
fp1: [1×1 Line]
i: 100
j: 100
m: 2
p: 0.1000
t: [1×101 double]
x: [1×101 double]
y: [1×101 double]
调取矩阵内容用A.A
取整函数
floor向下取整、ceil向上取整。round()向最近的数字取整,数字为0.5则取绝对值大的方向。
加减乘除
双精度浮点数参与运算时,返回值类型取决于其他参与数据类型。其他为逻辑、字符型,返回双精度;其它为整型,返回整型;其他为单精度,返回单精度。注意单精度浮点不能和整型进行算熟运算。
sum():求和,返回一个数。
prod():求积,返回一个数。
comsum():累和,返回数组。
cumprod():累乘,返回数组。
nthroot(a,n):计算一个数a的n次方跟。注意,负数只能开奇次方根。
realpow([1,2,3], [1,2,3]):使用realpow计算实数指数。两个参数,分别是底和指数。
关系运算
不等号用~=
标量减去数组,表示标量减去数组的每一个元素,得到新数组。10-A
数组操作
创建一个从1到9的数组(类似python的range()函数):A = 1:9
创建带步长的数组:A = 1: step: 9,默认为1
单元数组cell(类似numpy中的array):同行用逗号,不同行用分号。C={'x', [1,2] ; 2, 3}
创建空数组:c = cell(2, 4)
单元数组的寻访:c(2,2)——取第2行2列的单元,属性为cell。 c{2,2}——取第2行2列的内容,属性为数据类型。
数组合并:c={a b},简单排列。
删除单元:c{m,n} = []
数组的乘除法:为对应元素的乘除,所用符号不是普通的乘除法符号,而是点乘、点除。(这点非常友好,避免和矩阵乘除法搞混淆)
数据的点积:C = dot(A, B) 或者 C=sum(A.*B)
寻找非零元素的索引和值:find(A)
矩阵操作
矩阵是数学概念,数组是计算机概念。计算机中,矩阵是数组的子集。
矩阵构造:
ones(n),全1矩阵;ones(size(A))表示和A一样规模的全1矩阵;
zeros(n):全0矩阵;
eye(n):单位矩阵;eyes(m,n);
diag(x):以向量x元素为对角线的矩阵;
diag(A, k):矩阵A的第k条对角线组成的向量。主对角线为k=0,下三角对角线为k<0,上三角对角线为k>0;
triu(A):构建上三角矩阵,元素取自A
tril(A):构建下三角矩阵,元素取自A
构建向量:
行向量:a=[1 2 3]
列向量:b=[1;2;3]
矩阵元素访问:
A(1):第一个元素
A(:, j):第j列
A(:, j:k):第j列到第k列向量组成的子矩阵
函数操作:
sum(A(:, end)),取最后一列的所有元素和
sum(A):对A进行列求和,得到一行。
isvector()、isempty()、issparse()——是否稀疏矩阵
cat(DIM, A, B):矩阵拼接,DIM=1表示按行垂直拼接,DIM=2表示按列水平拼接
矩阵合并:空格表示行合并,分号表示列合并
特殊矩阵
希尔伯特矩阵Hilbert:hilb(n)
托普利兹矩阵Toeplitz:toeplitz(n)
魔方矩阵:magic(n),每行、列和两条对角线上的元素相等
斯帕卡矩阵:pascal(n)
范德蒙矩阵:vander(v)
字符串操作
String = 'I am good!'
查看字符串长度:size(String)
截取子串:String(1:2) ,得到‘st’。下标从1开始。截取时包含最后一位。
字符串查找:findstr(String, 'm')
字符串替换:strrep(String, 'm', '000')
函数调用
直接调用:一个文件只能有一个主函数,主函数与文件同名。子函数只能被主函数调用。
间接调用:用@创建函数句柄。Func = @func_name
mean():平均值
median():中位数
sign():符号函数
cumsum(x):累积和
cumprod(x):累积连乘
fft(x):离散傅里叶变换
多个函数的代码可写到同一个文件里。第一个是主函数,其他是子函数。子函数只能被同一m文件调用。
所有函数第一行是函数声明行。
随机数
rand(n):n维随机矩阵;
randn(m,n,...,p):正态分布随机数;
unidrnd(N):生成一个最大为N、最小为1 的随机整数。
randi()函数生成均匀分布的伪随机整数,范围为imin--imax,如果没指定imin,则默认为1。
r = randi(imax,n):生成n*n的矩阵
r = randi(imax,m,n):生成m*n的矩阵
r = randi([imin,imax],...)
unidrnd和randi有什么区别?
randi可以有负整数,但是unidrnd没有。当然可以减去一个数得到。
unidrnd会快那么一点点。
randperm(n):randperm(n)可以产生1到n的整数的无重复的随机排列。
那么我们要想得到6个(1,10)之间的随机数的话,只需要 a=randperm(1:10),再取其前6个即可a(1:6)。
find函数:
k = find(X) 返回向量或者矩阵中不为0的元素的位置索引。
k = find(X,n) 返回与 X 中的非零元素对应的前 n 个索引。
k = find(X,n,direction)(其中 direction 为 'last')查找与 X 中的非零元素对应的最后 n 个索引。direction 的默认值为 'first',即查找与非零元素对应的前 n 个索引。
[row,col] = find(___) 使用前面语法中的任何输入参数返回数组 X 中每个非零元素的行和列下标。
[row,col,v] = find(___) 还返回包含 X 的非零元素的向量 v。
结构体
可通过赋值创建:Student.Name = 'wag'
可通过struct创建:Student = struct('Name', 'wang')
类
classdef name
properties
end
methods
end
调用类自己用 obj(替代Python中的self)。
通常一个类应该包含四个基本的成员函数:
构造函数 ―― 与类名相同,可以在其中完成成员初始化的工作;
显示函数 ―― 名为display,用于显示成员的数据;
赋值函数 ―― 名为set,用于设置类成员的数值;
取值函数 ―― 名为get,用于读取类成员的函数。
使用属性set方法来验证分配给属性的值。 属性set方法可以执行诸如对输入值进行错误检查之类的操作,然后再采取任何必要的操作来存储新的属性值。
值类设置函数set 必须将修改后的对象返回给调用函数。 处理类不需要返回修改后的对象。
MATLAB中,类成员变量都是private的,必须在成员函数中访问。因此就不能箱struct那样,用d.x和d.y等形式访问其成员变量了。不过,这个问题不严重,编个专门的成员函数get就行了。另外,成员函数的调用有个跟普通的函数一样。注意在get和set函数中,成员变量是以字符串的形式指定的,要通过字符串比较的办法进行区分,然后对输出变量进行赋值。
classdef TensileData % 定义类的名称
properties %% 定义类的属性,相当于C++中的成员函数
Material = 'carbon steel';
SampleNumber = 0;
Stress
Strain
end
properties (Dependent) %% 定义依赖型属性,该属性只能通过类内的方法进行赋值,参考modulus = get.Modulus(obj)
Modulus
end
methods %% 定义类的方法
function td = TensileData(material,samplenum,stress,strain) %方法一:非依赖型属性做输入参数
if nargin > 0
td.Material = material;
td.SampleNumber = samplenum;
td.Stress = stress;
td.Strain = strain;
end
end % TensileData
end
methods %% 定义类的方法
function obj = set.Material(obj,material)
if ~(strcmpi(material,'aluminum') ||...
strcmpi(material,'stainless steel') ||...
strcmpi(material,'carbon steel'))
error('Material must be aluminum, stainless steel, or carbon steel')
end
obj.Material = material;
end % Material set function
function modulus = get.Modulus(obj)
ind = find(obj.Strain > 0); % Find nonzero strain
modulus = mean(obj.Stress(ind)./obj.Strain(ind));
end % Modulus get function
function obj = set.Modulus(obj,~) % 不能显式定义依赖型属性变量
fprintf('%s%d\n','Modulus is: ',obj.Modulus)
error('You cannot set Modulus explicitly');
end
function disp(td)
fprintf(1,'Material: %s\nSample Number: %g\nModulus: %1.5g\n',...
td.Material,td.SampleNumber,td.Modulus);
end % disp
function plot(td,varargin)
plot(td.Strain,td.Stress,varargin{:})
title(['Stress/Strain plot for Sample ',num2str(td.SampleNumber)])
xlabel('Strain %')
ylabel('Stress (psi)')
end % plot
end
methods (Access = 'private') % 只能通过类的成员进行访问 私有成员方法
function m = CalcModulus(td)
% Over-simplified calculation of Elastic Modulus
ind = find(td.Strain > 0); % Find nonzero strain
m = mean(td.Stress(ind)./td.Strain(ind));
end % CalcModulus
end
end % classdef
for循环、while循环
for i = 1: 10
while command
注意循环内部语句需要加分号结尾
matlab遍历数组的两种方式:
(1)下标遍历:for i=1:length(v)
(2)元素遍历:for ve=v
注意:元胞数组遍历的时候,ve是1*1 cell,要访问之需用ve{1}。具体见https://blog.csdn.net/iwantnon/article/details/4378567
绘图
点图:plot(x,y,'r*');
线图:plot(x,y,'r-');
点线图:plot(x,y,'-r*');
MATLAB 中如何对时间序列类数据进行排序的同时对其下标进行同步排序
有时候我们不但想要对数据进行排序而且想要同时对其下标进行同步排序。
例如时间序列数据 Y =[6,3,1,9],其对应时间下标数据为:T=[1,2,3,4]。如何在对Y序列数据进行排序的同时,也对其对应的时间序列数据进行同步排序?
这里给出一个思路:
T = [1,2,3,4];
Y = [6,3,1,9];
[Y_new,id] = sort(Y)
T_new = T(id)
最后结果:
T_new =[3,2,1,4]
Y_new =[1,3,6,9]
小世界网络
% The simulation of WS-smallworld network
% the algorithm of WS-smallworld's generation has been improved in speed,
% and tend to be easily understood
% writen by winter-my-dream@hotmail.com
% Example:
% N = 100; %network size (number of nodes)
% m = 6; %2*m is the average edges of each nodes
% p = 0.1; %rewiring probability
% matrix = small_world_WS_new(N,m,p);
function matrix = small_world_WS_new(N,m,p)
rng('default');
rng('shuffle');
matrix=zeros(N,N);
% generate regular network
for i=m+1:N-m
matrix(i,i-m:i+m)=1;
end
for i=1:m
matrix(i,1:i+m)=1;
end
for i=N-m+1:N
matrix(i,i-m:N)=1;
end
for i=1:m
matrix(i,N-m+i:N)=1;
matrix(N-m+i:N,i)=1;
end
% rewiring the network
for i = 1:N
% then rewiring the edges with the probability of p
[series1,series2] = range_sort(N,m,i);
index0 = series1(rand(2*m,1)>1-p);
if(~isempty(index0))
matrix(i,index0) = 0;
matrix(i,series2(randperm(length(series2),length(index0))))=1;
end
end
matrix = matrix -diag(diag(matrix));
end
function [series1,series2] = range_sort(N,m,i)
% select the index of nodes in row i for rewiring
if(i-m>0 && i+m<=N)
series1 = i-m:i+m;
series2 = setdiff(1:N,series1);
elseif(i-m<=0)
series1 = [1:i+m,N-m+i:N];
series2 = setdiff(1:N,series1);
else
series1 = [1:m-N+i,i-m:N];
series2 = setdiff(1:N,series1);
end
% Without considering the connection of diagonal elements
series1(series1==i) = [];
end
function matrix = small_world_NW(N,m,p)
% N=50;m=3;p=0.1;
% matrix=sparse([]);
matrix = zeros(N,N);
for i=m+1:N-m
matrix(i,i- m:i+m)=1;
end
for i=1:m
matrix(i,1:i+m)=1;
end
for i=N-m+1:N
matrix(i,i- m:N)=1;
end
for i=1:m
matrix(i,N-m+i:N)=1;
matrix(N- m+i:N,i)=1;
end
% Random add edge
kk = (rand(N,N)<p);
matrix = logical(matrix + kk);
matrix = matrix -diag(diag(matrix));
end