Potential Bugs in CalibrateBIHAModel.m
I’ve been reviewing the function
CalibrateBIHAModel.m from the VFI Toolkit and found several issues that look like bugs, especially in the logmoments section. I’m sharing them here in case it is helpful for maintainers or other users.
1. Overwriting caliboptions.logmoments
Inside the logmoments block, the code does:
logmomentnames = caliboptions.logmoments;
caliboptions.logmoments = zeros(nummoments,1);
But later it accesses fields like:
caliboptions.logmoments.AllStats.(...)
At that point, caliboptions.logmoments is no longer a struct but a numeric vector, so this should fail.
Suggested fix
Use logmomentnames instead:
logmomentnames.AllStats.(...)
2. Incorrect field existence checks
The code uses patterns like:
any(fieldnames(logmomentnames),'AllStats')
This is not valid MATLAB syntax for membership testing.
Suggested fix
any(strcmp(fieldnames(logmomentnames),'AllStats'))
or better:
isfield(logmomentnames,'AllStats')
3. Likely typo / undefined variables
Several variables appear inconsistent or undefined:
acscummomentsizesacsmomentnamesacsmomentsizes
But earlier naming suggests variables such as:
autocorrcummomentsizescrossseccummomentsizesautocorrmomentnames
These look like copy-paste errors and would likely trigger runtime errors.
4. Wrong struct referenced in Cross-Section block
In the CrossSecCovarCorr section, I see:
caliboptions.logmoments.AutoCorrTransProbs.(...)
This appears incorrect. It should likely be something like:
logmomentnames.CrossSecCovarCorr.(...)
This looks like a copy-paste bug from the autocorrelation section.
5. Suspicious use of lsqnonlin
The function calls:
lsqnonlin(CalibrationObjectiveFn,calibparamsvec0,[],[],[],[],[],[],[],minoptions)
This does not match the standard MATLAB signature for lsqnonlin.
Expected pattern
lsqnonlin(fun,x0,lb,ub,options)
This may error or behave unexpectedly depending on MATLAB version.
6. Repeated parameter transformation inside loop
At the end, the code appears to do:
for pp=1:ncalibparams
calibparamsvec = ParameterConstraints_TransformParamsToOriginal(...);
Params.(calibparamnames{pp}) = calibparamsvec(pp);
end
The transformation is applied inside the loop, which is inefficient and may be logically incorrect.
Suggested fix
calibparamsvec = ParameterConstraints_TransformParamsToOriginal(...);
for pp=1:ncalibparams
Params.(calibparamnames{pp}) = calibparamsvec(pp);
end
7. Minor inconsistency in comments
In the constraint description, I noticed:
p = A + (B - a) * y
Lowercase a should likely be uppercase A. This is only a comment issue, but it may indicate that this block deserves a careful recheck.
Overall assessment
Most issues are concentrated in the logmoments block and look like copy-paste or refactoring mistakes. Some of them, especially points 1 to 4, are likely to break execution.