Background
- 关于在python中调用matlab函数,我之前已经写过两篇文章了,非常详细,且之前的方法可以不用安装matlab程序,只需要按照mcr运行环境就行了。
- 具体可以参考:【java和python调用matlab程序详细记录】【Python 高效率传参调用 MATLAB 程序】
- 这里介绍另一种方式,直接调用matlab源码中的函数,前提条件是需要按照matlab软件哈
- 具体可以参考官方网站哈:【从 Python 中调用 MATLAB】
1、处理逻辑
-
首先已经安装好了matlab软件和python3,具体对应关系如下所示
-
python交互是通过json传递参数
-
python与matlab交互是通过mat文件传递文件
-
python主程序与matlab源码在同一目录下
2、参数文件
- input.json
python主程序输入文件
{"pcs": 5, "mcs": 5, "nn": 124, "lsna": [1, 2, 3, 3, 1, 2, 4, 3, 5, 6, 8, 6, 8, 11, 9, 13, 16, 20, 9, 13, 16, 20, 57, 7, 12, 14, 17, 19, 26, 31, 37, 49, 53, 7, 12, 14, 17, 19, 26, 31, 37, 49, 53, 78, 10, 15, 18, 22, 10, 15, 18, 22, 25, 23, 24, 27, 29, 33, 35, 39, 45, 55, 61, 23, 24, 27, 29, 33, 35, 39, 45, 55, 61, 83, 30, 32, 34, 36, 38, 41, 44, 46, 48, 62, 64, 30, 32, 34, 38, 21, 28, 21, 28, 40, 42, 40, 43, 47, 41, 44, 46, 48, 51, 52, 56, 60, 63, 50, 50, 54, 51, 58, 52, 56, 60, 63, 68, 59, 65, 66, 67, 69, 71, 70, 65, 66, 67, 69, 71, 74, 70, 75, 77, 79, 81, 76, 72, 72, 73, 80, 85, 87, 84, 77, 81, 76, 73, 88, 86, 85, 87, 89, 90, 91, 90, 91, 93, 92, 94, 92, 94, 96, 95, 97, 95, 97, 98, 99, 100, 101, 103, 106, 99, 99, 100, 101, 102, 104, 109, 107, 102, 107, 103, 115, 105, 108, 105, 112, 111, 112, 114, 111, 110, 113, 117, 116, 116, 118, 118, 119, 117, 120, 122, 122, 123, 64], "lena": [2, 4, 4, 5, 7, 14, 6, 8, 11, 8, 11, 9, 16, 20, 13, 16, 20, 57, 19, 26, 31, 37, 78, 12, 14, 17, 19, 26, 31, 37, 49, 53, 78, 10, 15, 18, 22, 25, 35, 39, 45, 55, 61, 83, 15, 18, 22, 25, 21, 28, 24, 27, 29, 24, 27, 29, 33, 35, 39, 45, 55, 61, 83, 30, 32, 36, 38, 41, 44, 46, 48, 62, 64, 84, 32, 34, 36, 38, 41, 44, 46, 48, 62, 64, 84, 40, 42, 43, 47, 28, 30, 59, 66, 42, 43, 50, 47, 51, 52, 56, 60, 63, 52, 56, 60, 63, 68, 58, 54, 67, 58, 69, 71, 74, 70, 73, 80, 65, 66, 67, 69, 71, 74, 74, 75, 77, 79, 81, 82, 76, 72, 77, 79, 81, 82, 82, 76, 73, 80, 85, 87, 89, 89, 88, 88, 86, 86, 90, 91, 93, 106, 115, 91, 93, 92, 94, 96, 94, 96, 95, 97, 98, 97, 98, 99, 100, 101, 100, 101, 103, 106, 115, 108, 105, 102, 104, 109, 107, 114, 111, 104, 109, 110, 121, 108, 119, 112, 114, 114, 117, 116, 118, 113, 118, 119, 117, 120, 120, 121, 122, 123, 123, 123, 124, 124, 85], "lla": [2.15671640044499, 5.12227288255451, 1.21559549127594, 2.8685942058528, 4.10144336613248, 4.00802400508674, 1.25907045077685, 1.64558440413782, 2.11233075175363, 1.78072960829242, 1.72441482493349, 1.52645499456934, 1.68864254036293, 2.09084982385543, 1.24796144573164, 1.29268116632377, 1.05222707894883, 8.24440020985296, 2.12979007233584, 1.94600329739162, 1.92858064730479, 1.86928131962412, 2.26631612771802, 2.84773233312071, 0.91603967156679, 1.37400488212546, 0.549013875947417, 1.52220025331178, 1.2009526545091, 1.26992567755903, 3.10987567725624, 0.972244557689523, 4.90009884121811, 0.603565224138119, 0.605292845636354, 0.575613699684704, 0.56049586433972, 0.597641963428771, 1.10097572019062, 0.929407787483942, 0.741950221301982, 0.617435914266963, 0.769211901848245, 0.846785720279563, 2.83070273146707, 1.10108640444554, 1.21441820396195, 0.600739252152988, 1.97446019986285, 2.2857369226437, 0.683879459310971, 0.659387828199463, 0.608830199949775, 0.585066802720082, 0.93382093811509, 0.749984011547142, 0.547211757964319, 0.698641912060672, 1.17368376999116, 1.39235959637904, 3.20317126015454, 0.921499400039975, 4.92379730982962, 0.939357832814496, 0.743333687232064, 0.803975131639537, 0.778933999978495, 0.772395154375175, 0.765503841808482, 0.812004475101565, 0.659140064386486, 0.794995195025646, 0.744582771403599, 0.472787205357974, 1.01980122648249, 0.336491154654265, 0.34208033741354, 0.696605025305785, 0.540228132958264, 0.716123630873786, 1.02363570011129, 1.51557795978326, 3.18844573786438, 0.826089412577796, 4.98560234966658, 0.89672724905905, 0.712466291146579, 0.695394913117758, 1.25158507442092, 2.01258941956435, 1.67913287254928, 4.73244117852567, 3.6916415377871, 1.29989751221685, 0.529195179695275, 1.16794361180765, 0.613866884665271, 0.402686031507573, 1.51264216172891, 1.51952947259494, 1.50535252369964, 1.68699179985061, 0.476398859900416, 0.725052816819047, 1.18029432563995, 1.37467224189035, 1.12409411377964, 2.31338920648923, 0.477650614379763, 1.35283380005667, 0.522535078627838, 1.36309407875459, 1.92271651741577, 1.75078833050129, 1.07881053645512, 0.856840383638944, 1.34473316889858, 4.10871491354686, 0.827862008868441, 0.994734611311844, 1.74636284382963, 0.441739751555005, 1.09399806391808, 1.13823285439513, 1.11031567910812, 1.11188844983986, 1.1510644042185, 1.16243833509788, 0.89227273490284, 0.363334664683093, 0.16281672351833, 1.46725678457344, 1.12944536659124, 1.1265312686471, 0.613174126112401, 1.37483697896418, 1.08728495937321, 1.24177701767394, 1.24217969798618, 2.55092842220331, 3.13451431118652, 2.30916273751913, 2.16970299090732, 3.1442871311042, 2.04437429793797, 2.25363689104415, 3.10029737333697, 1.01445638302299, 1.82803105163122, 4.51332613283977, 6.0319766441023, 6.07514151832315, 2.85824376700256, 1.84757511777624, 1.36875384826703, 0.950966095589683, 1.45072097215803, 2.23436506470631, 2.57822857894362, 0.789398574817027, 0.9640788805393, 0.766338102088423, 2.14100130709854, 2.13428940280286, 1.42201907040333, 1.01638289364255, 0.957018661311206, 1.96481757091066, 1.65334328860528, 2.18578427741689, 1.07146037419195, 1.48951760299307, 1.52046966639119, 1.55393498194389, 0.625078858612541, 0.497702314397347, 0.781421388679559, 0.302111872229239, 0.371087724338307, 0.311002718661141, 1.42384166146268, 1.15977264194648, 0.772691663946919, 1.5342724819262, 0.806920344808863, 1.27378774070307, 0.755973916217826, 1.01236132275863, 0.963461810188238, 0.889963959330747, 0.668282733024534, 0.930274028933665, 0.770448584127849, 1.28187341267087, 1.32768020924551, 0.53596771881884, 1.04398585205531, 0.338535407577645, 3.87386516169159, 1.10789314981831, 1.12784803602482, 1.10566508450551, 1.13632999929841, 1.902803005619, 1.16631360264543, 2.98369174488475], "msna": [1, 1, 2, 2, 2, 2, 2, 3, 2, 2, 4, 3, 3, 3, 4, 6, 8, 6, 9, 9, 10, 10, 21, 21, 28, 28, 59, 28, 40, 77, 79, 69, 67, 58, 58, 50, 58, 52, 47, 43, 32, 32, 24, 18, 22, 14, 25, 19, 13, 26, 33, 41, 44, 41, 52, 76, 71, 71, 56, 56, 56, 44, 70, 60, 31, 16, 11, 20, 20, 37, 48, 48, 63, 63, 72, 73, 73, 20, 20, 57, 57, 53, 53, 53, 45, 61, 78, 64, 84, 84, 87, 87, 89, 89, 89, 89, 89, 50, 115, 106, 106, 87, 92, 94, 96, 96, 95, 97, 99, 100, 100, 101, 104, 108, 114, 111, 110, 113, 118, 116, 120, 68, 122, 123, 118, 118, 21, 64], "mena": [2, 2, 4, 4, 4, 4, 4, 4, 14, 14, 6, 8, 8, 8, 6, 8, 11, 9, 13, 19, 15, 15, 28, 28, 30, 66, 65, 66, 50, 88, 81, 81, 69, 69, 69, 58, 69, 71, 51, 47, 42, 34, 27, 24, 27, 17, 29, 26, 26, 35, 35, 44, 46, 52, 71, 82, 74, 74, 74, 74, 74, 56, 74, 70, 39, 31, 20, 37, 37, 45, 63, 63, 68, 73, 73, 86, 86, 57, 57, 78, 78, 78, 78, 78, 55, 83, 83, 84, 89, 89, 89, 89, 115, 115, 115, 115, 115, 54, 121, 115, 115, 106, 94, 96, 98, 98, 97, 98, 100, 101, 101, 103, 107, 119, 116, 118, 113, 118, 121, 120, 123, 80, 124, 124, 121, 121, 59, 85], "mga": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 4, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 1, 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 2, 4], "nea": [41, 52, 114], "fml": [[1.0, 1.0, 0.0201135144400038, 0.00485259976677354, 0.000256888802765694, 5.8681307981977e-05], [1.0, 2.0, 0.93631329417954, 0.00367535964490481, 4.61236139452523e-05, 5.2765962379722e-06], [1.0, 3.0, 0.0201135144400038, 0.00485259976677354, 0.000256888802765694, 5.8681307981977e-05], [1.0, 4.0, 0.93631329417954, 0.00367535964490481, 4.61236139452523e-05, 5.2765962379722e-06], [2.0, 1.0, 0.163033040960304, 0.0646563187163703, 0.00810557013534307, 0.0026993448361335], [2.0, 2.0, 0.997425325869211, 0.0796358085745737, 0.00418053399069939, 0.000866565101226897], [2.0, 3.0, 0.163033040960304, 0.0646563187163703, 0.00810557013534307, 0.0026993448361335], [2.0, 4.0, 0.997425325869211, 0.0796358085745737, 0.00418053399069939, 0.000866565101226897], [3.0, 1.0, 0.360716661128008, 0.186385916106235, 0.037652492973923, 0.0155143475328584], [3.0, 2.0, 0.999801594194935, 0.253707014776233, 0.0292138893599325, 0.0084733179278164], [3.0, 3.0, 0.360716661128008, 0.186385916106235, 0.037652492973923, 0.0155143475328584], [3.0, 4.0, 0.999801594194935, 0.253707014776233, 0.0292138893599325, 0.0084733179278164]]}
- output.json
python主程序输出文件,程序会自动生成
{"qg_pre": 3.31452, "qg_post_matrix": [[3.31452, 3.31452, 3.31452, 3.31452, 3.31452], [3.31452, 3.29032, 3.31452, 3.31452, 3.31452], [3.25806, 3.23387, 3.25806, 3.29032, 3.25806]]}
input.mat
和output.mat
这两个文件程序也会自动生成。
2、源码
import sys
import json
from numpy import array
from scipy.io import savemat, loadmat
import matlab.engine
class Const:
"""常量"""
STR_TYPE = 'str'
LIST_TYPE = 'list'
ARRAY_TYPE = 'array'
# python交互输入文件,默认当前目录
INPUT_PYTHON = 'input.json'
# python交互输出文件,默认当前目录
OUTPUT_PYTHON = 'output.json'
# matlab交互输入文件,默认当前目录
INPUT_MATLAB = 'input.mat'
# matlab交互输出文件,默认当前目录
OUTPUT_MATLAB = 'output.mat'
# matlab函数function_loss_cal的输入参数变量名
MATLAB_INPUT_KEYS = {
'mcs': STR_TYPE,
'nn': STR_TYPE,
'lsna': LIST_TYPE,
'lena': LIST_TYPE,
'lla': LIST_TYPE,
'msna': LIST_TYPE,
'mena': LIST_TYPE,
'mga': LIST_TYPE,
'nea': LIST_TYPE,
'fml': ARRAY_TYPE
}
# matlab函数function_loss_cal的输出参数变量名
MATLAB_OUTPUT_KEYS = {'qg_pre': STR_TYPE, 'qg_post_matrix': ARRAY_TYPE}
def test_write_input_json():
"""测试-准备一个测试的json输入文件"""
output = {}
mat_input = loadmat(Const.INPUT_MATLAB)
for key in Const.MATLAB_INPUT_KEYS:
key_type = Const.MATLAB_INPUT_KEYS[key]
key_input = mat_input[key].tolist()
if key_type == Const.STR_TYPE:
val = key_input[0][0]
elif key_type == Const.LIST_TYPE:
val = key_input[0]
elif key_type == Const.ARRAY_TYPE:
val = key_input
output[key] = val
json_data = json.dumps(output)
with open(Const.INPUT_PYTHON, "w", encoding='utf8') as fw:
fw.write(json_data)
def json_to_mat():
"""计算输入参数
1.读取json输入文件,默认为当前目录下的input.json;
2.把结果写入到mat输入文件,默认为当前目录下的input.mat
"""
with open('input.json', "r", encoding='utf8') as fr:
res = json.load(fr)
for key in res:
key_type = res[key]
if key_type == Const.LIST_TYPE:
res[key] = array(res[key])
savemat(Const.INPUT_MATLAB, res, False)
def call_matlab_func():
"""调用matlab函数"""
# MATLAB Engine API
eng = matlab.engine.start_matlab()
eng.function_loss_cal(nargout=0)
eng.quit()
def mat_to_json():
"""计算输出结果
1.读取mat输出文件,默认为当前目录下的output.mat;
2.写json输出文件,默认为当前目录下的output.json
"""
output = {}
mat_output = loadmat(Const.OUTPUT_MATLAB)
for key in Const.MATLAB_OUTPUT_KEYS:
key_type = Const.MATLAB_OUTPUT_KEYS[key]
key_output = mat_output[key].tolist()
if key_type == Const.STR_TYPE:
val = key_output[0][0]
elif key_type == Const.LIST_TYPE:
val = key_output[0]
elif key_type == Const.ARRAY_TYPE:
val = key_output
output[key] = val
json_data = json.dumps(output)
with open(Const.OUTPUT_PYTHON, "w", encoding='utf8') as fw:
fw.write(json_data)
def main():
"""主函数"""
# 测试数据
# test_write_input_json()
# 准备计算参数
json_to_mat()
# 调用算法计算
call_matlab_func()
# 输出计算结果
mat_to_json()
if __name__ == '__main__':
"""函数入口"""
main()