Inner matrix dimensions must agree and too many input variables

1 次查看(过去 30 天)
I have now been 'debugging' my code for the past fortnight without getting anywhere and frustration is mounting.
I am trying to calibrate the Heston Model to option data using LSQNONLIN. And I keep getting a combination of 'Not enough input variables.', 'Too many input variables.' and 'Inner matrix dimensions must agree.'
I have used 'whos' to find out which input variables are vectors and which are skalars to no avail and I have used a combination of global variables and anonymous functions as well. So I would like to get some guidance as to how to progress.
Below is the script for calibration:
%Marketdata=[strike, maturity,impvol,time till expiry]
%Strike: Strike price of options
%Maturity: (1=Prompt month, 2=Prompt month+1,...)
%Impvol: Market Implied vol
%Time till expiry: Days until option expires
clear all
global impvol; global K; global t; global S0; global r; global q;
%Initial Parameter Guess for Hestion Model
%V(1), Kappa, Theta, Vol of Volatility (sig), Correlation (rho)
x0=[.5,.5,.5,.05,.5];
lb = [0, 0, 0, 0,-.9];
ub = [1, 100, 1, .5,.9];
M=50000;
filename='Option_Data.xlsx'
sheet='Data'
address='I2';
[num,txt,raw]=xlsread(filename);
numrows=length(num);
numcolumns=min(size(num));
numoptions= numrows-1;
for i=1:numcolumns
v2struct(struct(eval(sprintf('txt{i}')),num(:,i)))
end
t=T(:);
K=Strike(:);
S0=Spot(:);
r=r;
q=q;
for w=1:numrows
impvol(w)=blsimpv(Spot(w),K(w),r(w),T(w),Mid(w),10,[],[],Option(w));
end
impvol(find(isnan(impvol))) = 0;
x = lsqnonlin(@costf2,x0,lb,ub);
Below is the costf2:
function [cost]=costf2(x)
global impvol; global K; global t; global S0; global r; global q; global u;
u=2;
for y=1:length(t)
cost(y)=blsprice(S0,K(y),r(y),t(y),impvol(y))-Lewis(u,S0(y),K(y),t(y),r(y),q(y),x(1),x(2),x(3),x(4),x(5));
end
and finally the option pricing formula:
function [ call ] = Lewis(u,S0,K,t,r,q,v0,kappa,eta,theta,rho)
global K; global t; global S0; global r; global q; global u; global v0; global kappa; global eta; global theta; global rho;
% call= S0.*exp(-q.*t)-sqrt(S0.*K).*exp(-(r+q).*t./2)/pi.*integral(integrand(u,S0,K,t,r,q,v0,kappa,eta,theta,rho),0,u);
call= S0*exp(-q*t)-sqrt(S0*K)*exp(-(r+q)*t/2)/pi.*integral(@integrand,0,u);
end
% function [heston] = integrand(u,S0,K,t,r,q,v0,kappa,eta,theta,rho)
function [heston] = integrand(x)
y=exp(1i*u*log(S0/K)*((r-q)*t).*CF_SVj(u,S0,t,r,q,v0,kappa,eta,theta,rho));
heston=real(y)/(u^2+0.25);
end
function [fj]=CF_SVj(u,S0,t,r,q,v0,kappa,eta,theta,rho)
d=((rho.*theta.*(u-1i./2).*1i-kappa)).^2-theta.^2.*(-1i.*(u-1i./2)-(u-1i./2).^2).^.5;
g=(kappa-rho.*theta.*(u-1i./2).*1i)./(kappa-rho.*theta.*(u-1i./2).*1i+d);
a = exp(1i.*(u-1i./2).*(log(S0+(r-q).*t)));
b=exp(eta.*kappa.*theta.^-2.*((kappa-rho.*theta.*(u-1i./2)*.1i-d).*t-2*log((1-g.*exp(-d.*t))./(1-g))));
c=exp(v0^.2.*theta.^-2.*(kappa-rho.*theta*.1i.*(u-1i./2)-d).*(1-exp(-d.*t)./(1-g.*exp(-d.*t))));
fj=a.*b.*c;
end
Any advice?
  2 个评论
Jan
Jan 2016-2-16
Please post the complete error messages. Most of all the line matters, which causes the error. Note that you cannot get a combination of errors, because Matlab stops at the first error. Omit the "clear all", because it impedes the debugging. Never never never use the evil eval. Lines like this are simply too strange:
v2struct(struct(eval(sprintf('txt{i}')),num(:,i)))
karsten
karsten 2016-2-16
This is the entire error message:
Error using *
Inner matrix dimensions must agree.
Error in Lewis (line 4)
call=
S0*exp(-q*t)-sqrt(S0*K)*exp(-(r+q)*t/2)/pi.*integral(@integrand,0,u);
Error in costf2 (line 5)
cost(y)=blsprice(S0,K(y),r(y),t(y),impvol(y))-Lewis(u,S0(y),K(y),t(y),r(y),q(y),x(1),x(2),x(3),x(4),x(5));
Error in lsqnonlin (line 194)
initVals.F =
feval(funfcn{3},xCurrent,varargin{:});
Error in HestonCalibration (line 46)
x = lsqnonlin(@costf2,x0,lb,ub);
Caused by:
Failure in initial user-supplied objective function
evaluation. LSQNONLIN cannot continue.
Regarding the very strange code. It creates a range of vectors with the headername in the excel sheet. However crude, I find that quite useful :) And the clear just lets me reset and the console is less cluttered. I'm obviously a novice at this.

请先登录,再进行评论。

回答(2 个)

Bjorn Gustavsson
Bjorn Gustavsson 2016-2-16
At the command-line prompt do this:
>> dbstop if error
That makes matlab stob inside the function that gives you the error and give you a prompt and access to the workspace of the function (and all the calling functions as well). Once you get the error you can check the sizes of all your variables the usual ways (whos, size(), etc). and you can execute the different operations in the error-causing line. Then you will find which variable have sizes that doesn't match.
HTH
  2 个评论
karsten
karsten 2016-2-16
The problem is, in this instance, it stops in the LSQNONLIN program, and thus whos returns this:
Name Size Bytes Class Attributes
EXITFLAG 0x0 0 double
FUN 1x1 32 function_handle
FVAL 0x0 0 double
JACOB 0x0 0 double
LAMBDA 0x0 0 double
LB 1x5 40 double
OUTPUT 0x0 0 double
Resnorm 0x0 0 double
UB 1x5 40 double
caller 1x9 18 char
defaultopt 1x1 4556 struct
earlyTermination 1x1 1 logical
flags 1x1 715 struct
funValCheck 1x1 1 logical
funfcn 1x5 616 cell
lb 5x1 40 double
msg 0x0 0 char
mtxmpy 1x1 32 function_handle
optim_ME 1x1 738 MException
optionFeedback 1x1 1330 struct
options 0x0 0 double
problemInput 1x1 1 logical
sizes 1x1 184 struct
ub 5x1 40 double
userFcn_ME 1x1 3441 MException
varargin 0x0 0 cell
xCurrent 1x5 40 double
xstart 5x1 40 double
None of which are parameters in my model and really leads me nowhere. But I will plug on. Thanks!
Bjorn Gustavsson
Bjorn Gustavsson 2016-2-17
That seems at odds with the error-message you gave earlier, there you say that the error occurs in the Lewis function.
Either you've now got another error or something more obscure has happened. What is the error message this time around? What does the command dbstack return? Perhaps you can get some further information of interest by walking up (or down?) in the call stack by using dbup/dbdown and look at variables in the corresponding workspaces.
HTH

请先登录,再进行评论。


Steven Lord
Steven Lord 2016-2-17
I would make a couple changes.
  1. DON'T use global variables unless you absolutely, positively MUST do so -- and even then, think if there's a way to avoid them. They make debugging of code very difficult (as you're discovering) and they allow any function with access to the global workspace (any function) to manipulate how your function works.
  2. If you need to pass many additional parameters between your functions, pack them into a struct array and pass that one struct array around, extracting parameters from it as needed. This will help with suggestion 1.
  3. To debug this particular issue, call WHOS immediately before the line in your Lewis function where the error occurs. Using the information displayed immediately before the error occurs can help you figure out what variable is a different size than you expect. Then you need to determine why it's a different size.
  4. EVAL may seem nice and useful. But it too complicates the debugging process and will make your code slower to execute (because it's harder for MATLAB to optimize if variables can pop into existence at runtime.)

类别

Help CenterFile Exchange 中查找有关 Variables 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by