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.

 Accepted Answer

Matt J
Matt J on 12 Nov 2020
Edited: Matt J on 12 Nov 2020
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 Comments

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.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!