Supplied objective function must return a scalar value

When I analyze the stock's return style through share model,I want to determine the sensitive coefficients through the fmincon code of Matlab. However, I encounter some problem about "supplied objective function must return a scalar value", anyone who can help me? Thank you very much.
E=xlsread("data.xlsx")
F=E(:,1) % the target stock return time series (with 755*6 matrix)
G=E(:,2) % the large cap return time series (with 755*1 matrix)
H=E(:,3) % the mid cap return time series (with 755*1 matrix)
I=E(:,4) % the small cap return time series (with 755*1 matrix)
J=E(:,5) % the aggregate bond return time series (with 755*1 matrix)
K=E(:,6) % the treasury time series (with 755*1 matrix)
Benchmark=[G,H,I,J,K]
fun=@(x)var(F-Benchmark.*x) % establishing the objective function (with 1*1 value)
x0=[0,0,0,0,1] % the initial point
A=[]
b=[] % no inequity constraints
Aeq=ones(1,5)
beq=1 % equity constraints
lb=zeros(1,5) % lower bound
ub=ones(1,5) % upper bound
x=fmincon(fun,x0,A,b,Aeq,beq,lb,ub)
In principle, the output of x should be a 5*1 matrix. However, I always get the error that "supplied objective function must return a scalar value". In fact, fun can be handled with value. So I can not understand the "supplied objective function mus t trturn a scalar value". Anyone who can help me? Thank you very much. The data is included in the attachment.

 Akzeptierte Antwort

Matt J
Matt J am 12 Nov. 2020
Bearbeitet: Matt J am 12 Nov. 2020

0 Stimmen

The objective function must return a scalar value, because fmincon is trying to minimize it. It needs to be able to make comparisons like fun(x1)<fun(x2) and that will only be possible if fun(x) returns a scalar. If you think fun(x) should already be returning a scalar value, you should check to see if that's true.

5 Kommentare

Excuse me:
fun(x) can be seen as a scalar as the picture indicated. So I can not understand this error.
You build Benchmark out of a series of column vectors, so Benchmark is a 2D array with 5 columns. You do element-wise multiplication of the 2D vector with x, and x is going to be a row vector, so Benchmark.*x will be a 2D array with 5 columns. F is a column vector with the same number of rows as Benchmark has, so (starting from R2016b) it is valid to do the subtraction, and you would get out a 2D array with the same number of rows and columns as Benchmark has.
Now you take var() of that 2D array. When you apply var() to a 2D array, it operates along the first non-scalar dimension. Provided that the data file had more than one row of data, the first non-scalar dimension would be rows. So var() is going to take the variance of each row, which would give you are result that has one row and 5 columns.
A result that has one row and 5 columns is not a scalar value.
You should always test your objective function before giving it to fmincon.
E=rand(10,6); %Fake data
F=E(:,1);
G=E(:,2);
H=E(:,3);
I=E(:,4);
J=E(:,5);
K=E(:,6);
Benchmark=[G,H,I,J,K];
fun=@(x)var(F-Benchmark.*x);
x0=[0,0,0,0,1];
A simple preliminary test shows that fun does not return a scalar,
fx0 = fun(x0)
fx0 = 1×5
0.0658 0.0658 0.0658 0.0658 0.1442
Thank you, Benchmark.*x is indeed a 755*5 matrix rather than a 1*1 scalar. Accordingly, I have changed the form of x dividing it into x(1),x(2),x(3),x(4) and x(5), and eventually solved the error.
Thank you very much.
Benchmark * x.'
might have been appropriate. That would be 755 x 5 * 5 x 1, which would give you a 755 x 1 result. Subtract that from a 755 x 1 result would give you a 755 x 1 result. var() of a 755 x 1 result would give you a scalar.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Community Treasure Hunt

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

Start Hunting!

Translated by