Python 高效率传参调用 MATLAB 程序

本文介绍了如何在Python中调用MATLAB脚本进行损伤预测,涉及MAT文件的读写、MATLAB神经网络模型及Python调用MATLAB的包装与执行。测试案例是一个基于BP神经网络的损伤预测程序,通过输入数据计算损伤值并保存结果到MAT文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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源码

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()

附赠:matlab一键打包压缩脚本

  • package.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 自动打包脚本【通用脚本,固定步骤,请勿修改】
% 在该脚本的当前路径下直接运行即可打包生成新的zip算法包
% 前提条件:压缩文件目录和算法源码主函数文件名相同
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear;clc
 
% 获取被打包的函数文件名
currentDir = pwd;
[filepath,~,~] = fileparts(currentDir);
[~,filename,~] = fileparts(filepath);

% 打包步骤
cd ../..;
packageOutput='packageOutput/';
file=[currentDir, '/', filename, '.m'];
theoutputdir=[packageOutput, filename];
theoutputfile=[packageOutput, 'setup.py'];
zipfilename=[filename, '.zip'];
compiler.build.pythonPackage(file, ...
    'PackageName',filename, ...
    'OutputDir',packageOutput, ...
    'Verbose', 'off');
movefile(theoutputdir, filename,'f');
movefile(theoutputfile, filename,'f');
rmdir(packageOutput, 's');
if exist(zipfilename, 'file')~=0
    delete(zipfilename)
end
zip(zipfilename, filename);
disp('Success!');
fprintf("Here it is '%s'!\n", zipfilename);

在这里插入图片描述

  • matlab算法源码 electric_damage_state_ct.m

matlab读写json文件可以参考这篇文章:【matlab读写json文件

function electric_damage_state_ct()
% electric_damage_state_ct-某某算法
% 输入:
%         mcs-输入参数1
%         seismics-输入参数2
% 输出:
%         nodeds-输出参数1
%         lineds-输出参数2

%% 输入数据
pcs=3;
input=loadjson('input.json');
mcs=input.mcs;
seismics=input.seismics;
if isfield(input,pcs)
    pcs=input.pcs;
end

%% 数据处理
pcs=cast(pcs, 'double');
pcs=-pcs;

%% 算法逻辑
disp('很复杂的算法逻辑!');

%% 输出数据
output = struct('nodeds', nodeds, 'lineds', lineds);
savejson('', output, 'output.json');
end
  • 通用交互主函数 main.py
import electric_damage_state_ct
import warnings
from wlfutil.all import UniUtil

# 忽略告警
warnings.filterwarnings("ignore")


def call_matlab_func():
    """调用matlab函数"""
    mf = electric_damage_state_ct.initialize()
    mf.electric_damage_state_ct(nargout=0)
    mf.terminate()


@UniUtil.time_cost
def main():
    """主函数
    cost 8.22s
    """
    # 调用算法计算
    call_matlab_func()


if __name__ == '__main__':
    """函数入口"""
    main()

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WaiSaa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值