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
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)))
回答(2 个)
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 个评论
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
2016-2-17
I would make a couple changes.
- 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.
- 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.
- 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.
- 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.)
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!