com.meliorbis.economics.aggregate.ByShockLevelAggregateSolver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ModelSolver Show documentation
Show all versions of ModelSolver Show documentation
A library for solving economic models, particularly
macroeconomic models with heterogeneous agents who have model-consistent
expectations
package com.meliorbis.economics.aggregate;
import static com.meliorbis.numerics.DoubleArrayFactories.createArrayOfSize;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.ArrayUtils;
import com.meliorbis.economics.model.Model;
import com.meliorbis.economics.model.ModelConfig;
import com.meliorbis.economics.model.ModelException;
import com.meliorbis.economics.model.State;
import com.meliorbis.economics.model.StateWithControls;
import com.meliorbis.numerics.generic.primitives.DoubleArray;
import com.meliorbis.numerics.index.IndexIterator;
import com.meliorbis.numerics.index.impl.Index;
import com.meliorbis.numerics.threading.ComputableRecursiveAction;
import com.meliorbis.utils.Pair;
import com.meliorbis.utils.Timer;
import com.meliorbis.utils.Timer.Stoppable;
import com.meliorbis.utils.Utils;
public abstract class ByShockLevelAggregateSolver, M extends Model>
extends AggregateSolverBase
{
public ByShockLevelAggregateSolver(M model_, C config_)
{
super(model_, config_);
}
/**
* Hook called when aggregate expectations have been calculated based on the aggregate transition.
*
* Default does nothing
*
* @param state_ The state of the calculation
*/
protected void afterAggregateExpectationUpdate(S state_)
{
}
@Override
protected Pair, DoubleArray>> calculateAggregatePolicies(final S state_)
{
final Timer timer = new Timer();
Stoppable stoppable = timer.start("deriveAggTrans");
final DoubleArray> newTransition = createArrayOfSize(state_.getAggregateTransition().size());
final DoubleArray> newControlsPolicy = (state_ instanceof StateWithControls>) ? createArrayOfSize(((StateWithControls>) state_).getCurrentControlsPolicy().size()) : null;
// Create an index with each possible shock value, so they can be
// iterated over
List shockSizes = new ArrayList();
Utils.addLengthsToList(shockSizes, state_.getConfig().getAggregateExogenousStates());
Index aggShocksIndex = new Index(Utils.toIntArray(shockSizes));
IndexIterator shockIterator = aggShocksIndex.iterator();
List actions = new ArrayList();
prepareAggregatePolicyCalculation(state_);
// Fill the implied transition for that level of aggregate shock.
final int[] fillDims = ArrayUtils.add(
// It varies by aggregate state...
Utils.sequence(0, _config.getAggregateEndogenousStateCount()),
// ...and includes all aggregate states/controls
newTransition.numberOfDimensions()-1 - _config.getAggregateExogenousStateCount());
// For each potential value of the aggregate shock
while (shockIterator.hasNext())
{
shockIterator.nextInt();
{
// The combination of aggregate shock values to perform the
// derivation for
final int[] currentShockIndexes = shockIterator.getCurrentIndex().clone();
actions.add(()->{
try
{
Stoppable innerDerive = timer.start("innerDerive");
Pair, DoubleArray>> newTransForState = calculateTransitionForShocks(currentShockIndexes, state_);
innerDerive.stop();
final int[] stateDimSelector = Utils.repeatArray(-1, state_.getConfig().getAggregateEndogenousStateCount() + state_.getConfig().getAggregateControlCount() + currentShockIndexes.length);
// Be sure to copy the appropriate state's transition
System.arraycopy(currentShockIndexes, 0, stateDimSelector, _config.getAggregateEndogenousStateCount() + state_.getConfig().getAggregateControlCount(), currentShockIndexes.length);
Stoppable fillTimer = timer.start("fillAggTrans");
newTransition.at(stateDimSelector).fillDimensions(newTransForState.getLeft(), fillDims);
fillTimer.stop();
if(newTransForState.getRight() != null)
{
newControlsPolicy.at(stateDimSelector).fillDimensions(newTransForState.getRight(), fillDims);
}
} catch (ModelException e)
{
//completeExceptionally(e);
}
});
}
}
Stoppable execTimer = timer.start("gradExec");
getNumerics().getExecutor().executeAndWait(actions);
execTimer.stop();
stoppable.stop();
return new Pair, DoubleArray>>(newTransition, newControlsPolicy);
}
/**
* Subclasses should implement this to calculate the updated forecasting function conditional on the
* provided current shocks
*
* @param currentShockIndexes_ The current shock to update the forecasting
* function for
* @param state_ The current calc state
*
* @return The new forecasting function calculated
*
* @throws ModelException In the event of Model-Specific failure.
*/
abstract protected Pair,DoubleArray>> calculateTransitionForShocks(final int[] currentShockIndexes_, S state_) throws ModelException;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy