All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.meliorbis.economics.infrastructure.simulation.AbstractSimulator Maven / Gradle / Ivy

Go to download

A library for solving economic models, particularly macroeconomic models with heterogeneous agents who have model-consistent expectations

There is a newer version: 1.1
Show newest version
package com.meliorbis.economics.infrastructure.simulation;

import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.meliorbis.economics.infrastructure.Base;
import com.meliorbis.economics.model.Model;
import com.meliorbis.economics.model.ModelException;
import com.meliorbis.economics.model.State;
import com.meliorbis.economics.utils.FileUtils;
import com.meliorbis.numerics.generic.MultiDimensionalArray;
import com.meliorbis.numerics.io.NumericsWriter;
import com.meliorbis.numerics.io.NumericsWriterFactory;
import com.meliorbis.utils.Timer;
import com.meliorbis.utils.Timer.Stoppable;

/**
 * Abstract class providing shared functionality for use by simulators
 * 
 * @author Tobias Grasl
 *
 * @param  The type of ISimState to use
 * @param  The type of shocks, Integer for discrete and Double for continuous
 */
public abstract class AbstractSimulator extends Base implements Simulator
{
	protected static final Logger LOG = Logger.getLogger(AbstractSimulator.class.getName());
	
	protected String _logSims = System.getProperty("com.meliorbis.simulator.traceDir");
	final protected SimulationObserver _observer;

	public AbstractSimulator()
	{
		super();
		_observer = SimulationObserver.silent();
	}
	
	public AbstractSimulator(NumericsWriterFactory writerFactory_)
	{
		super(writerFactory_);
		
		_observer = SimulationObserver.silent();
	}
	
	public AbstractSimulator(NumericsWriterFactory writerFactory_, AggregateSimulationObserver observer_)
	{
		super(writerFactory_);
		_observer = observer_;
	}

	

	@Override
	public , M extends Model> SimulationResults simulateShocks(
			S simState_, 
			MultiDimensionalArray shocks_,
			M model_,
			SC calcState_,
			SimulationObserver observer_) throws ModelException
	{
	
		Timer timer = new Timer();
	
		Stoppable stoppable = timer.start("Simulate");
		int period = 0;
	
		S state = simState_;
		SimulationResults results = new SimulationResults();
	
		AggregateSimulationObserver observer = new AggregateSimulationObserver(_observer, observer_);
		observer.beginSimulation(state, calcState_, model_, shocks_.size()[0]);
		
		while (period < shocks_.size()[0] - 1)
		{			/*
			 * Calculate individual future choices from current to future state
			 * given current and future shocks, and determine current aggregate
			 * controls along the way
			 */
			MultiDimensionalArray futureShocks = shocks_.at(period + 1);
			TransitionRecord record = simulateTransition(state, model_, calcState_, shocks_.at(period), futureShocks);
	
			if (LOG.isLoggable(Level.FINE))
			{
				LOG.fine(String.format("Shocks: %s,States: %s, Agg Controls: %s", shocks_.at(period), record.getStates(), record.getControls()));
			}
	
			/*
			 * Record the current state - not this is the aggregate state from
			 * before the transition, but we had to wait to get the controls,
			 * which are calculated in the transition function
			 */
			results.addPeriod(shocks_.at(period), record.getStates(), record.getControls());
	
			observer.periodSimulated(state, record, calcState_, period);
	
			/*
			 * Move forward
			 */
			state = record._resultingDist;
	
			period++;
	
			if (period % 100 == 0)
			{
				System.out.print(".");
			}
			if (period % 1000 == 0)
			{
				System.out.println((int) period / 1000);
			}
		}
	
		observer.endSimulation(state, calcState_);
	
		results.setFinalState(state);
	
		stoppable.stop();
		return results;
	}
	
	/* (non-Javadoc)
	 * @see com.meliorbis.economics.infrastructure.ISimulator#simulateShocks(com.meliorbis.economics.infrastructure.simulation.SimState, com.meliorbis.numerics.generic.impl.GenericBlockedArray, M, S, com.meliorbis.economics.infrastructure.ISimulationObserver, java.io.File, java.lang.String)
	 */
	@Override
	public , M extends Model> SimulationResults simulateShocks(S simState_,
			MultiDimensionalArray shocks_, M model_, SC calcState_, SimulationObserver observer_, File outputDir_,
			String resultsPath_) throws SimulatorException, ModelException
	{
		SimulationResults results = simulateShocks(simState_, shocks_, model_, calcState_, observer_);

		File resultsDir = writeSimResults(results, outputDir_, resultsPath_, "");
		
		observer_.wroteSimulation(results, calcState_, resultsDir);
		_observer.wroteSimulation(results, calcState_, resultsDir);
		
		return results;
	}
	
	/**
	 * Writes the provided results to the parent directory using the given name
	 * 
	 * @param results_ The results to be written
	 * @param parent_ The parent directory to write to
	 * @param relPath_ The path relative to parent to write to
	 * @param postFix_ The postfix to append to the path
	 * 
	 * @return A file-object referencing the written data
	 * 
	 * @throws SimulatorException In the event of failure
	 */
	protected File writeSimResults(SimulationResults results_, 
			File parent_, String relPath_, 
			String postFix_) throws SimulatorException
	{
		File targetFile;

		if (relPath_ == null || relPath_.isEmpty())
		{
			// Create a dated target file
			targetFile = FileUtils.createDatedFile(parent_, "sim_" + postFix_);
		} else
		{
			targetFile = new File(parent_, relPath_ + postFix_);
		}

		final NumericsWriter numericsWriter = getNumericsWriter(targetFile);

		try
		{
			results_.write(numericsWriter);	
		} catch (IOException e)
		{
			throw new SimulatorException("Error writing sim results", e);
		} finally
		{
			try
			{
				numericsWriter.close();
			} catch (IOException e)
			{
			}
		}

		return targetFile;
	}

}