Potential Bugs in CalibrateBIHAModels

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:

  • acscummomentsizes
  • acsmomentnames
  • acsmomentsizes

But earlier naming suggests variables such as:

  • autocorrcummomentsizes
  • crossseccummomentsizes
  • autocorrmomentnames

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.


As it is probably clear, the post above was written by AI. I think it did a good job at flagging potential bugs.

Would be nice to document either in Pseudocodes or as comments in the m file that in general equilibrium there are two ways of calibrating:

  • Nested: Outer minimization over parameters, inner loop over general equilibrium prices
  • Joint: Include the GE prices among the parameters to calibrate and include the GE conditions among the targets. Do all in one.

Fixed them. (except the thing about lsqnonlin(), doesn’t appear to be an issue)

I am past halfway through creating a ‘Intro to Inf Horz’, it will likely cover that point about calibration.

2 Likes

I fixed some bugs that were wrecking my InfHorz Stationary Distribution (unbeknownst to me). So I may be withdrawing a number of my questions about what’s not working. :blush:

2 Likes

Nice, looking forward to this intro