Matlab中用类表示结构化数据
作者:互联网
目录
用类表示结构化数据
将对象作为数据结构体
以下示例定义用于存储具有特定结构的数据的类。使用一致的结构存储数据,从而更轻松地创建函数来操作数据。MATLAB® struct 可以包含说明特定数据元素的字段名称,这是一种有用的数据组织方式。但是,类可以定义数据存储(属性)和对该数据执行的操作(方法)。本示例说明了这些优点。
示例背景
对于本示例,数据表示拉伸应力/应变测量值。这些数据用于计算各种材料的弹性模数。简而言之,应力是施加在材料上的力,应变是由此产生的形变。其比率决定材料的特性。虽然这种方法是一个大大简化了的流程,但足以满足本示例的目的。
数据的结构
下表说明了数据的结构。
数据 | 说明 |
---|---|
Material | char标识被测材料的类型的向量 |
SampleNumber | 测试样本的编号 |
Stress | 表示测试过程中施加给样本的应力的数值向量。 |
Strain | 表示所施加应力对应值处应变的数值向量。 |
Modulus | 定义受测材料弹性模数的数值,该数值由应力和应变数据计算得出 |
TensileData 类
以下示例从类的简单实现开始,并以此实现为基础来说明特性如何增强类的有用性。该类的第一个版本仅提供数据存储。该类为每个必需的数据元素定义一个属性。
classdef TensileData
properties
Material
SampleNumber
Stress
Strain
Modulus
end
end
创建实例并赋给数据
以下语句将创建一个 TensileData 对象,并为其进行数据赋值:
td = TensileData;
td.Material = 'Carbon Steel';
td.SampleNumber = 001;
td.Stress = [2e4 4e4 6e4 8e4];
td.Strain = [.12 .20 .31 .40];
td.Modulus = mean(td.Stress./td.Strain);
类相对于结构体的优势
像处理任何 MATLAB 结构体一样处理 TensileData 对象(在以前的语句中为 td)。但是,相对于使用通用数据结构(例如 MATLAB struct),将特化数据结构体定义为类具有以下优势:
-
用户不小心拼错字段名称时会收到错误消息。例如,键入以下内容:
td.Modulis = ...
会直接在结构体中添加一个字段。但如果 td 是 TensileData 类的一个实例,则将返回错误。
-
类易于重用。一旦定义了类,就可以轻松地使用添加新属性的子类来扩展它。
-
类易于识别。类有名称,因此可以使用whos和class函数与工作区浏览器来识别对象。使用类名,可以轻松地用有意义的名称来引用记录。
-
赋值时,类可以验证各个字段值,包括类或值。
-
类可以限制对字段的访问,例如,允许读取某个特定字段,但不能更改该字段。
将属性限制为特定值
可以通过定义属性 set 访问方法,将属性限制为特定值。MATLAB 每次设置属性值时都会调用 set 访问方法。
Material 属性 set 函数
Material 属性 set 方法将属性的赋值限制为以下字符串之一:aluminum、stainless steel 或 carbon steel。将此函数定义添加到方法代码块中。
classdef TensileData
properties
Material
SampleNumber
Stress
Strain
Modulus
end
methods
function obj = set.Material(obj,material)
if (strcmpi(material,'aluminum') ||...
strcmpi(material,'stainless steel') ||...
strcmpi(material,'carbon steel'))
obj.Material = material;
else
error('Invalid Material')
end
end
end
end
当尝试设置Material属性时,MATLAB在设置属性值之前会调用set.Material方法。如果该值与可接受值匹配,函数便将属性设置为该值。set方法中的代码可以直接访问属性,以避免递归调用属性 set 方法。
例如:
td = TensileData;
td.Material = 'brass';
Error using TensileData/set.Material
Invalid Material
用构造函数简化接口
通过添加一个构造函数来简化与 TensileData 类的接口,该构造函数:
-
使能够将数据作为参数传递给构造函数
-
为属性赋值
该构造函数是一个与类同名的方法。
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
end
使用以下语句创建一个完整填充了数据的 TensileData 对象:
td = TensileData('carbon steel',1,...
[2e4 4e4 6e4 8e4],...
[.12 .20 .31 .40]);
按需计算数据
如果某个属性的值取决于其他属性的值,请使用 Dependent 特性定义该属性。MATLAB 不存储从属属性的值。当访问从属属性时,将使用从属属性 get 方法来确定属性值。当显示对象属性或作为显式查询的结果时,可以进行访问。
计算模数
TensileData 对象不存储 Modulus 属性的值。构造函数没有 Modulus 属性值的输入参数。Modulus 的值:
-
根据 Stress 和 Strain 属性的值计算得出
-
在 Stress 或 Strain 属性的值发生变化时也必定会改变
因此,最好仅在需要时计算 Modulus 属性的值。使用属性 get 访问方法计算 Modulus 的值。
Modulus 属性 get 方法
Modulus 属性取决于 Stress 和 Strain,因此其 Dependent 特性为 true。将 Modulus 属性放在单独的 properties 代码块中,并设置 Dependent 特性。
get.Modulus 方法计算并返回 Modulus 属性的值。
properties (Dependent)
Modulus
end
仅使用默认特性在 methods 代码块中定义属性 get 方法。
methods
function modulus = get.Modulus(obj)
ind = find(obj.Strain > 0);
modulus = mean(obj.Stress(ind)./obj.Strain(ind));
end
end
此方法在消除分母数据中的零后,计算应力与应变数据的平均比率。查询属性时,MATLAB 会调用
get.Modulus
的方法。例如:
td = TensileData('carbon steel',1,...
[2e4 4e4 6e4 8e4],...
[.12 .20 .31 .40]);
td.Modulus
ans =
1.9005e+005
Modulus 属性 set 方法
要设置 Dependent 属性的值,该类必须实现属性 set 方法。不需要允许显式设置 Modulus 属性。但您可以使用 set 方法提供自定义的错误消息。Modulus set 方法引用当前属性值,然后返回错误:
methods
function obj = set.Modulus(obj,~)
fprintf('%s%d\n','Modulus is: ',obj.Modulus)
error('You cannot set the Modulus property');
end
end
显示 TensileData
对象
TensileData 类重载 disp 方法。此方法控制命令行窗口中的对象显示。disp 方法显示 Material、SampleNumber、Modulus 属性的值。它不显示 Stress 和 Strain 属性数据。这些属性包含在命令行窗口中不容易查看的原始数据。
disp 方法使用fprintf 在命令行窗口中显示格式化的文本:
methods
function disp(td)
fprintf(1,...
'Material: %s\nSample Number: %g\nModulus: %1.5g\n',...
td.Material,td.SampleNumber,td.Modulus);
end
end
绘制应力对应变的图的方法
查看应力/应变数据图有助于确定材料在所施加的拉力范围内的行为。TensileData 类会重载 MATLAB plot函数。
plot 方法创建应力对应变数据的线性图,并添加标题和轴标签,从而生成一个拉力数据记录的标准化图:
methods
function plot(td,varargin)
plot(td.Strain,td.Stress,varargin{:})
title(['Stress/Strain plot for Sample',...
num2str(td.SampleNumber)])
ylabel('Stress (psi)')
xlabel('Strain %')
end
end
该方法的第一个参数是包含数据的 TensileData 对象。该方法将参数的变量列表 (varargin) 直接传递给内置 plot 函数。TensileData plot 方法允许传递线条设定符参数或属性名称-值对组。
例如:
td = TensileData('carbon steel',1,...
[2e4 4e4 6e4 8e4],[.12 .20 .31 .40]);
plot(td,'-+b','LineWidth',2)
TensileData
类概要
示例代码 | 讨论 |
---|---|
classdef TensileData | 值类支持对象的独立副本。 |
properties Material SampleNumber Stress Strain end | 参考数据结构 |
properties (Dependent) Modulus end | 查询时计算 Modulus。 |
methods | 有关方法的一般信息, 参考Oridinary 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 | 参考用构造函数简化接口。 参考类构造函数方法。 |
function obj = set.Material(obj,material) if (strcmpi(material,'aluminum') ||... strcmpi(material,'stainless steel') ||... strcmpi(material,'carbon steel')) obj.Material = material; else error('Invalid Material') end end | 限制 function m = get.Modulus(obj) ind = find(obj.Strain > 0); m = mean(obj.Stress(ind)./obj.Strain(ind)); end |
查询时计算 | |
function obj = set.Modulus(obj,~) fprintf('%s%d\n','Modulus is: ',obj.Modulus) error('You cannot set Modulus property'); end | 为 |
function disp(td) fprintf(1,'Material: %s\nSample Number: %g\nModulus: %1.5g\n',... td.Material,td.SampleNumber,td.Modulus) end | 重载 |
function plot(td,varargin) plot(td.Strain,td.Stress,varargin{:}) title(['Stress/Strain plot for Sample',... num2str(td.SampleNumber)]) ylabel('Stress (psi)') xlabel('Strain %') end | 重载plot函数以接受 |
end end |
展开类代码:
classdef TensileData
properties
Material
SampleNumber
Stress
Strain
end
properties (Dependent)
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
function obj = set.Material(obj,material)
if (strcmpi(material,'aluminum') ||...
strcmpi(material,'stainless steel') ||...
strcmpi(material,'carbon steel'))
obj.Material = material;
else
error('Invalid Material')
end
end
function m = get.Modulus(obj)
ind = find(obj.Strain > 0);
m = mean(obj.Stress(ind)./obj.Strain(ind));
end
function obj = set.Modulus(obj,~)
fprintf('%s%d\n','Modulus is: ',obj.Modulus)
error('You cannot set Modulus property');
end
function disp(td)
sprintf('Material: %s\nSample Number: %g\nModulus: %1.5g\n',...
td.Material,td.SampleNumber,td.Modulus)
end
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
end
end
标签:结构化,end,Material,中用,Matlab,obj,td,Modulus,属性 来源: https://blog.csdn.net/jk_101/article/details/111247278