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

repicea.simulation.metamodel.ExponentialModelImplementation Maven / Gradle / Ivy

There is a newer version: 1.5.2
Show newest version
/*
 * This file is part of the repicea-metamodels library.
 *
 * Copyright (C) 2024 His Majesty the King in Right of Canada
 * Author: Mathieu Fortin, Canadian Forest Service
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library is distributed with the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * Please see the license at http://www.gnu.org/copyleft/lesser.html.
 */
package repicea.simulation.metamodel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

import repicea.math.Matrix;
import repicea.simulation.metamodel.ParametersMapUtilities.InputParametersMapKey;
import repicea.stats.data.StatisticalDataException;

/**
 * An implementation of the exponential model.
 * @author Mathieu Fortin - April 2024
 */
class ExponentialModelImplementation extends AbstractModelImplementation {

	protected ExponentialModelImplementation(String outputType, MetaModel model, LinkedHashMap[] startingValues) throws StatisticalDataException {
		super(outputType, model, startingValues);
	}

	@Override
	double getPrediction(double ageYr, double timeSinceBeginning, double r1, Matrix parameters) {
		return computePrediction(parameters == null ? getParameters() : parameters,
				ageYr, 
				timeSinceBeginning, 
				r1);
	}
	
	static double computePrediction(Matrix parms, double ageYr, double timeSinceBeginning, double r1) {
		double b1 = parms.getValueAt(0, 0);
		double b2 = parms.getValueAt(1, 0);
		double pred = (b1 + r1) * Math.exp(-b2 * ageYr);
		return pred;
	}

	@Override
	Matrix getFirstDerivative(double ageYr, double timeSinceBeginning, double r1) {
		return computeDerivative(getParameters(), ageYr, timeSinceBeginning, r1);
	}

	static Matrix computeDerivative(Matrix parms, double ageYr, double timeSinceBeginning, double r1) {
		double b1 = parms.getValueAt(0, 0);
		double b2 = parms.getValueAt(1, 0);
		
		double exp = Math.exp(-b2 * ageYr);
		
		Matrix derivatives = new Matrix(2,1);
		derivatives.setValueAt(0, 0, exp);
		derivatives.setValueAt(1, 0, - ageYr * (b1 + r1) * exp);
		return derivatives;
	}
	
	@Override
	public boolean isInterceptModel() {return false;}

	@Override
	public List getEffectList() {
		return Arrays.asList(new String[] {"b1","b2"});
	}

	@Override
	List getParameterNames() {
		if (parameterIndexMap == null) {
			fixedEffectsParameterIndices = new ArrayList();
			fixedEffectsParameterIndices.add(0);
			fixedEffectsParameterIndices.add(1);
			parameterIndexMap = new LinkedHashMap();
			int lastIndex = 0;
			parameterIndexMap.put("b1", lastIndex++);
			parameterIndexMap.put("b2", lastIndex++);
			parameterIndexMap.put(CORRELATION_PARM, lastIndex++);
			if (!isVarianceErrorTermAvailable) {
				parameterIndexMap.put(RESIDUAL_VARIANCE, lastIndex++);
			}
			if (isRegenerationLagEvaluationNeeded) {
				parameterIndexMap.put(REG_LAG_PARM, lastIndex++);
			}
			Set names = parameterIndexMap.keySet();
			parameterNames = Arrays.asList(names.toArray(new String[] {}));
		}
		return parameterNames;
	}

	@Override
	public String getModelDefinition() {
		return "y ~ b1*exp(-b2*t)";
	}

	@SuppressWarnings("unchecked")
	@Override
	LinkedHashMap[] getDefaultParameters() {
		 LinkedHashMap[] inputMap = new LinkedHashMap[4];
		 LinkedHashMap oMap = new LinkedHashMap();
		 oMap.put(InputParametersMapKey.Parameter.name(), "b1");
		 oMap.put(InputParametersMapKey.StartingValue.name(), 2000 + "");
		 oMap.put(InputParametersMapKey.Distribution.name(), "Uniform");
		 oMap.put(InputParametersMapKey.DistParms.name(), new String[]{"0", "8000"});
		 inputMap[0] = oMap;
		 oMap = new LinkedHashMap();
		 oMap.put(InputParametersMapKey.Parameter.name(), "b2");
		 oMap.put(InputParametersMapKey.StartingValue.name(), 0.005 + "");
		 oMap.put(InputParametersMapKey.Distribution.name(), "Uniform");
		 oMap.put(InputParametersMapKey.DistParms.name(), new String[]{"0.00001", "0.05"});
		 inputMap[1] = oMap;
		 oMap = new LinkedHashMap();
		 oMap.put(InputParametersMapKey.Parameter.name(), AbstractModelImplementation.CORRELATION_PARM);
		 oMap.put(InputParametersMapKey.StartingValue.name(), 0.92 + "");
		 oMap.put(InputParametersMapKey.Distribution.name(), "Uniform");
		 oMap.put(InputParametersMapKey.DistParms.name(), new String[]{"0.80", "0.995"});
		 inputMap[2] = oMap;
		 oMap = new LinkedHashMap();
		 oMap.put(InputParametersMapKey.Parameter.name(), AbstractModelImplementation.RESIDUAL_VARIANCE);
		 oMap.put(InputParametersMapKey.StartingValue.name(), 10000 + "");
		 oMap.put(InputParametersMapKey.Distribution.name(), "Uniform");
		 oMap.put(InputParametersMapKey.DistParms.name(), new String[]{"0", "20000"});
		 inputMap[3] = oMap;
		 return inputMap;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy