fminunc error message multiple variables

Hello everyone!
I want to minimize the following function that I wrote:
function ll = ll_wbl(A, N, Y, X, sum_ll)
%A=theta, A(1)=beta, A(2)=kappa
lambda=exp(X*A(1));
ll=N*log(A(2))+(A(2)-1).*log(Y)-A(2).*log(lambda)-(Y./lambda).^A(2);
ll=-ll;
if sum_ll==true
ll=sum(ll);
end
%grad=sum(Y.*X);
end
over the vector A by using fminunc:
clc; clear;
data = xlsread('ema1996_reduced.xls', 'Sheet1');
UNDUR = data(:,1);
UI = data(:,2);
RR = data(:,3);
RRUI=data(:,4);
DR=data(:,5);
DRUI=data(:,6);
LWAGE=data(:,7);
TENURE=data(:,8);
NONWHITE=data(:,9);
% Store as Y and X matrices
N = size(data, 1);
Y = UNDUR;
X = [ones(N, 1) UI RR RRUI DR DRUI LWAGE TENURE NONWHITE];
A0=zeros(2,1);
% Optmizer settings
options = optimoptions(@fminunc, 'Algorithm', 'quasi-newton');
% Estimate model
[A, fval, exitflag, output ] = fminunc(@ll_wbl, A0, options, Y, X, true);
Unfortunately, this doesn't work out somehow.
I get the following error:
Not enough input arguments.
Error in ll_wbl (line 9)
if sum_ll==true
Error in fminunc (line 278)
f = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial objective function evaluation. FMINUNC cannot continue.
I don't understand what's going on here since I am a newbie. Maybe someone can help me out?
Thanks in advance!

 採用された回答

Stephan
Stephan 2019 年 1 月 6 日

1 投票

Hi,
fminunc is only able to pass the optimization variable to the objective function. Since your function needs additionally input arguments, you need to pass them to the objective function.
Read here:
Best regards
Stephan

12 件のコメント

mathxaz
mathxaz 2019 年 1 月 6 日
Hi,
thanks for your answer. I'm sorry, I'm not familiar with MATLAB language. Do you mean pass a variable, that I need to include the variable 'N' in my objective function since my function also needs N as an input?
I tried to do it but still get an error:
Input:
A0=zeros(2,1);
% Optmizer settings
options = optimoptions(@fminunc,'Algorithm','quasi-newton');
% Estimate model
[A, fval, exitflag, output] = fminunc(@ll_wbl, A0, options, N, Y, X, true);
Output:
A0=zeros(2,1);
% Optmizer settings
options = optimoptions(@fminunc,'Algorithm','quasi-newton');
% Estimate model
[A, fval, exitflag, output] = fminunc(@ll_wbl, A0, options, N, Y, X, true);
Error using fminunc (line 352)
FMINUNC requires all values returned by functions to be of data type double.
Stephan
Stephan 2019 年 1 月 6 日
編集済み: Stephan 2019 年 1 月 6 日
In your case it should look like:
[A, fval, exitflag, output] = fminunc(@(A)ll_wbl(A, N, Y, X, sum_ll), A0, options);
Note that you will have to define
sum_ll =true;
before your fminunc call
mathxaz
mathxaz 2019 年 1 月 6 日
Hi Stephan,
thank you so much for your effort!
Unfortunately, when I run the script:
A0=[0 0];
% Optmizer settings
options = optimoptions(@fminunc,'Algorithm','quasi-newton');
% Estimate model
[A, fval, exitflag, output] = fminunc(@(A)ll_wbl(A, N, Y, X, true), A0, options);
I still get an error message:
A0=[0 0];
% Optmizer settings
options = optimoptions(@fminunc,'Algorithm','quasi-newton');
sum_ll=true;
% Estimate model
[A, fval, exitflag, output] = fminunc(@(A)ll_wbl(A, N, Y, X, sum_ll), A0, options);
Error using fminunc (line 352)
FMINUNC requires all values returned by functions to be of data type double.
Also when defining sum_ll=true before running fminunc I get the same error message and cannot find where I went wrong... :(
Stephan
Stephan 2019 年 1 月 6 日
your function sets the result
ll = sum_ll
which results in data type logical not double. use this instead:
ll = double(sum_ll)
mathxaz
mathxaz 2019 年 1 月 6 日
There was one mistake in my function. I wanted to have the option that the function calculates the sum over all ll values, so the script of the function must be:
function ll = ll_wbl(A,N, Y, X, sum_ll)
%A=theta, A(1)=beta, A(2)=kappa
lambda=exp(X*A(1));
ll=N*log(A(2))+(A(2)-1).*log(Y)-A(2).*log(lambda)-(Y./lambda).^A(2);
ll=-ll;
if sum_ll==true
ll = sum(ll);
end
end
(I edited my original post).
Using the same script as before:
A0=[0 0];
% Optmizer settings
options = optimoptions(@fminunc,'Algorithm','quasi-newton');
% Estimate model
[A, fval, exitflag, output] = fminunc(@(A)ll_wbl(A, N, Y, X, true), A0, options);
Still using double or not using it I get the following error:
Error using fminunc (line 357)
Supplied objective function must return a scalar value.
My function ll_wbl returns a 1x9 double matrix when using sum_ll=true. Is this the problem?
Stephan
Stephan 2019 年 1 月 6 日
編集済み: Stephan 2019 年 1 月 6 日
yes this is not allowed. the result which has to be minimized has to be a scalar.
is ll a matrix?
the you can sum the values this way (in R2018b):
ll = sum(ll,'all');
in other releases use:
ll = sum(sum(ll))
mathxaz
mathxaz 2019 年 1 月 6 日
But the strange thing is, I tried the exact same thing with another distribution, there my function returns a 1x2 double matrix using sum_ll=true and everything works out:
function:
function ll = ll_poisson(beta, Y, X, sum_ll)
lambda = exp(X * beta);
ll = Y .* log(lambda) - log(factorial(Y)) - lambda;
ll = -ll;
if sum_ll == true
ll = sum(ll);
end
end
script:
n = 200;
b0 = 1;
b1 = 1;
b = [b0 b1]';
% Simulate data
X = [ones(n,1) rand(n,1)];
lambda = exp(X*b);
Y = poissrnd(lambda);
% Initial parameter vector
beta0 = zeros(2, 1);
% Optmizer settings
options = optimoptions(@fminunc, 'Algorithm', 'quasi-newton');
% Estimate model
[beta, fval, exitflag, output ] = fminunc(@ll_poisson, beta0, options, Y, X, true);
I don't get how poisson works out but wbl doesn't since in my opinion it's the exact same thing just using other functions & dimensions of matrices.
Stephan
Stephan 2019 年 1 月 6 日
編集済み: Stephan 2019 年 1 月 6 日
consider:
x = ones(1,5)
sum(x)
y = ones(5,1)
sum(y)
z = ones(3,3)
sum(z)
but:
sum(sum(z))
So if you apply sum to a vector no matter if row or column vector ,the result is a scalar .If you apply it to a matrix the result is a vector and you have to sum this again to get a scalar.
mathxaz
mathxaz 2019 年 1 月 6 日
I think if I sum up the sum my objective is the wrong one for calculating the Maximum Likelihood estimator for the function (which is my goal).
I'm not sure but there must be another possibility since it also worked for my poisson function.
Stephan
Stephan 2019 年 1 月 6 日
編集済み: Stephan 2019 年 1 月 6 日
your poisson function returns a scalar. fminunc returns 2 values, the result of the Optimization, but the function gives back a single value - this is why it works.
you can check this by removing the semicolon operator in this line:
ll = sum(ll);
fmincon calls the function severeal times, and in every call tgere comes ll as a scalar value back as result.
mathxaz
mathxaz 2019 年 1 月 6 日
Allright, I see the difference.
Then it might be useful to use sum(sum(ll)) although I still have to think about if it gives me what I want to :)
Thank you so much for your effort!!!
Stephan
Stephan 2019 年 1 月 6 日
please accept useful answers. i wish you success !

サインインしてコメントする。

その他の回答 (1 件)

カテゴリ

質問済み:

2019 年 1 月 6 日

コメント済み:

2019 年 1 月 6 日

Community Treasure Hunt

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

Start Hunting!

Translated by