Background
- python调用matlab脚本需要注意前置条件,具体参考官方文档:从 Python 中调用 MATLAB,大致就是两点:一是需要python和matlab版本对应,二是需要matlab运行环境mcr。具体安装配置可以参考:java和python调用matlab程序详细记录
- 调用方式分两种吧:一是使用matlab engine,二是把matlab程序打成python包。第二种在传递参数上效率高点,所以这里只介绍第二种。
- 测试用例:一个基于bp神经网络开发的损伤预测matlab程序,输入一组数据,输出一个损伤值,输入多组就会输出多个。我们首先把程序改写,输入是读mat输入文件,输出也是一个mat文件。在python中,接收到参数写入到mat输入文件中,然后调用matlab程序,最后从mat输出文件中获取结果就行了。
1、mat文件
- mat数据格式是Matlab的数据存储的标准格式。在Matlab中主要使用load()函数导入一个mat文件,使用save()函数保存一个mat文件。
- load,save函数具体用法请参考官方文档:load函数用法,save函数用法
2、scipy
- Scipy 是基于 Numpy 的科学计算库,提供了许多的操作numpy的数组的函数。
- scipy.io包提供了多种功能来解决不同格式的文件的输入和输出。
- 在python中可以使用scipy.io中的函数loadmat()读取mat文件,函数savemat保存文件。
3、测试用例matlab源码
- 下载地址:https://pan.baidu.com/s/13VX1nm6Qj9TdWowLnnj_lw,提取码:king
- 注意:输入文件必须写全路径,打包的时候这个文件是不存在的,后面python调用前会先生成这个文件放到指定位置。
function predict_damage()
%{
params:截面高度,截面宽度,腹板厚度,翼缘厚度,钢材屈服强度,柱高,轴压比,温度,柱中竖向位移
res:返回损伤值
注意:输入参数按顺序逗号分隔;输出一个数据
%}
clear;
% 关闭告警
warning('off')
%% 输入数据-转置归一化
% 输入文件
load C:\Users\ssyc\sim_input.mat sim_input;
input_params=sim_input';
lines=size(sim_input, 1);
load predict.mat predict;
predict_p=zeros(9, 2398);
fmt_sim_input=zeros(9, lines);
for i=1:9
predict_p(i,:)=predict(:,i)';
end
for i=1:9
fmt_sim_input(i,:)=(input_params(i,:)-min(predict_p(i,:)))/(max(predict_p(i,:))-min(predict_p(i,:)));
end
%% BP神经网络
% 创建网络
threshold=[0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1];
net=newff(threshold,[9,1],{'logsig','logsig'},'trainlm');
% 设置训练参数
net.IW{1,1}=struct2array(load('IW.mat'));
net.LW{2,1}=struct2array(load('LW.mat'));
net.b=struct2array(load('b.mat'));
% 损伤预测
sim_output=sim(net,fmt_sim_input);
%% 保存预测结果到mat文件中
save('sim_output', 'sim_output')
end
4、matlab源码打python包
- 在当前目录进入shell后执行安装命令
python3 setup.py install
- 然后就可以在python代码中引用这个方法了
5、python中调用方式
from scipy.io import savemat, loadmat
from numpy import array
from com.wlf import predict_damage
def ssyc():
"""损伤预测"""
matlab_func = predict_damage.initialize()
matlab_func.predict_damage(nargout=0)
matlab_func.terminate()
def main():
"""主函数"""
# 这里测试给了三组数据,每组数据9个
sp = [
[0.1500, 0.1500, 0.0070, 0.0100, 235.0000, 3.0000, 0.5000, 225.0000, 2.9403],
[0.175, 0.175, 0.0075, 0.011, 235, 3.3, 0.2, 400, 7.9905],
[0.3, 0.3, 0.01, 0.015, 390, 3, 0.1, 100, 1.1919]
]
file_input, file_output = 'sim_input.mat', 'sim_output.mat'
data_input = {'sim_input': array(sp)}
savemat(file_input, data_input)
ssyc()
data_output = loadmat(file_output)
sim_output = data_output['sim_output'][0]
print(list(sim_output))
if __name__ == '__main__':
main()