필터 지우기
필터 지우기

Passing varargin to class function from Python with MATLAB.Engine

조회 수: 10 (최근 30일)
Juan Rasines
Juan Rasines 2024년 3월 12일
댓글: Shubham 2024년 6월 5일
I have the following MATLAB class function that I need to call from Python:
classdef CF1 < PROBLEM
methods
%% Default settings of the problem
function Setting(obj)
obj.M = 2;
if isempty(obj.D); obj.D = 10; end
obj.lower = zeros(1,obj.D);
obj.upper = ones(1,obj.D);
obj.encoding = ones(1,obj.D);
end
%% Calculate objective values and constraint violations
function Population = Evaluation(obj,varargin)
X = varargin{1};
X = max(min(X,repmat(obj.upper,size(X,1),1)),repmat(obj.lower,size(X,1),1));
D = size(X,2);
J1 = 3 : 2 : D;
J2 = 2 : 2 : D;
PopObj(:,1) = X(:,1) + 2*mean((X(:,J1)-repmat(X(:,1),1,length(J1)).^(0.5*(1+3*(repmat(J1,size(X,1),1)-2)/(D-2)))).^2,2);
PopObj(:,2) = 1-X(:,1) + 2*mean((X(:,J2)-repmat(X(:,1),1,length(J2)).^(0.5*(1+3*(repmat(J2,size(X,1),1)-2)/(D-2)))).^2,2);
PopCon = 1 - PopObj(:,1) - PopObj(:,2) + abs(sin(10*pi*(PopObj(:,1)-PopObj(:,2)+1)));
Population = SOLUTION(X,PopObj,PopCon,varargin{2:end});
obj.FE = obj.FE + length(Population);
end
%% Generate points on the Pareto front
function R = GetOptimum(obj,N)
R(:,1) = (0:1/20:1)';
R(:,2) = 1 - R(:,1);
end
end
end
I can evaluate the methods 'Setting()' and 'GetOptimum()' easily with the following Python code:
import numpy as np
import matlab.engine
eng = matlab.engine.start_matlab()
% Set the correct path with eng.cd('/path/to/CF1.m', nargout=0)
prob = eng.CF1()
eng.Setting(prob, nargout=0)
out = eng.GetOptimum(prob, 10)
print(np.array(out))
But I can't seem to match the 'varargin' input variable correctly from Python. I have tried passing a matlab.double(10 * [1.0]), a Python list (10 * [1.0]), a Python dictionary ({"1": 10 * [1.0]}), but I get the following errors for the first two and last attempt, respectively:
matlab.engine.MatlabExecutionError: Undefined function 'Evaluation' for input arguments of type 'CF1'
ValueError: invalid field for MATLAB struct
Any guidance on how to match the expected varargin argument from python would be much appreciated!
Juan

답변 (1개)

Shubham
Shubham 2024년 3월 22일
Hey Juan,
It seems that you require help when calling MATLAB functions from python using MATLAB Engine API that accept "varargin" as argument to the function call. The "varargin" keyword is used in MATLAB to accept variable number of input arguments.
In order to call the "Evaluation" method, you should pass the arguments directly after the object ("prob"). The first argument expected by "Evaluation" method is a matrix ( X=varargin{1}; ).
Passing a "matlab.double()" should not produce an error and can be passed into the "Evaluation" method.
I have modified the provided code snippets and tried at my end:
classdef CF1
methods
%% Calculate objective values and constraint violations
function Population = Evaluation(obj,varargin)
X = varargin{1};
Population = X.*2;
end
%% Generate points on the Pareto front
function R = GetOptimum(obj,N)
R(:,1) = (0:1/20:1)';
R(:,2) = 1 - R(:,1);
end
end
end
Python script:
import numpy as np
import matlab.engine
eng = matlab.engine.start_matlab()
# Set the correct path with eng.cd('/path/to/CF1.m', nargout=0)
prob = eng.CF1()
out = eng.GetOptimum(prob, 10)
print(" printing output of GetOptimum")
print(np.array(out))
X = np.random.rand(2, 2)
print(" printing random matrix of 2x2")
print(X)
print(" printing output of Evaluation method")
X_matlab = matlab.double(X.tolist())
population = eng.Evaluation(prob, X_matlab, nargout=1)
print(population)
Produced output:
Since you are using the input to "Evaluation" method as a matrix, you should keep in mind the resulting MATLAB data types when calling a function. The python dict is converted to a struct. You can have a look at the following documentation:
For converting a python dict to MATLAB struct, please refer to this MATLAB Answer:
For troubleshooting the Undefined function error, please have a look at the following:
I hope this helps!
  댓글 수: 1
Shubham
Shubham 2024년 6월 5일
Hey @Juan Rasines, did you find the above answer helpful? If so, could you please mark the anwer as accepted.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Call MATLAB from Python에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by