package org.openlca.core.model;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Embeddable;
/**
* Represents the uncertainty distributions supported by openLCA. Three fields
* are reserved for distribution parameters: <br>
* <br>
*
* parameter 1:
* <ul>
* <li>Normal distribution: arithmetic mean value
* <li>Lognormal distribution: geometric mean value
* <li>Triangle distribution: min value
* <li>Uniform distribution: min value
* <li>None: mean / resulting amount
* </ul>
*
* parameter 2:
* <ul>
* <li>Normal distribution: arithmetic standard deviation
* <li>Lognormal distribution: geometric standard deviation
* <li>Triangle distribution: most likely value (mode)
* <li>Uniform distribution: max value
* </ul>
*
* parameter 3:
* <ul>
* <li>Triangle distribution: max value
* </ul>
*
* Each distribution parameter can take a value and additionally a formula.
*
*/
@Embeddable
public class Uncertainty {
@Column(name = "distribution_type")
private UncertaintyType distributionType = UncertaintyType.NONE;
@Column(name = "parameter1_value")
private Double parameter1Value;
@Column(name = "parameter1_formula")
private String parameter1Formula;
@Column(name = "parameter2_value")
private Double parameter2Value;
@Column(name = "parameter2_formula")
private String parameter2Formula;
@Column(name = "parameter3_value")
private Double parameter3Value;
@Column(name = "parameter3_formula")
private String parameter3Formula;
/**
* Creates default distribution with type set to NONE and the first
* parameter set with the given mean value.
*/
public static Uncertainty none(double mean) {
Uncertainty uncertainty = new Uncertainty();
uncertainty.setDistributionType(UncertaintyType.NONE);
uncertainty.setParameter1Value(mean);
return uncertainty;
}
/**
* Creates a normal distribution.
*
* @param mean
* the arithmetic mean.
* @param sd
* the arithmetic standard deviation.
*/
public static Uncertainty normal(double mean, double sd) {
Uncertainty uncertainty = new Uncertainty();
uncertainty.setDistributionType(UncertaintyType.NORMAL);
uncertainty.setParameter1Value(mean);
uncertainty.setParameter2Value(sd);
return uncertainty;
}
/**
* Creates a log-normal distribution.
*
* @param gmean
* the geometric mean.
* @param gsd
* the geometric standard deviation
*/
public static Uncertainty logNormal(double gmean, double gsd) {
Uncertainty uncertainty = new Uncertainty();
uncertainty.setDistributionType(UncertaintyType.LOG_NORMAL);
uncertainty.setParameter1Value(gmean);
uncertainty.setParameter2Value(gsd);
return uncertainty;
}
/**
* Creates a uniform distribution.
*
* @param min
* the minimum.
* @param max
* the maximum.
*/
public static Uncertainty uniform(double min, double max) {
Uncertainty uncertainty = new Uncertainty();
uncertainty.setDistributionType(UncertaintyType.UNIFORM);
uncertainty.setParameter1Value(min);
uncertainty.setParameter2Value(max);
return uncertainty;
}
/**
* Creates a triangle distribution.
*
* @param min
* The minimum value.
* @param mode
* The most likely value (the mode).
* @param max
* The maximum value.
*/
public static Uncertainty triangle(double min, double mode, double max) {
Uncertainty uncertainty = new Uncertainty();
uncertainty.setDistributionType(UncertaintyType.TRIANGLE);
uncertainty.setParameter1Value(min);
uncertainty.setParameter2Value(mode);
uncertainty.setParameter3Value(max);
return uncertainty;
}
@Override
public Uncertainty clone() {
Uncertainty clone = new Uncertainty();
clone.setDistributionType(getDistributionType());
clone.setParameter1Formula(getParameter1Formula());
clone.setParameter2Formula(getParameter2Formula());
clone.setParameter3Formula(getParameter3Formula());
clone.setParameter1Value(getParameter1Value());
clone.setParameter2Value(getParameter2Value());
clone.setParameter3Value(getParameter3Value());
return clone;
}
public UncertaintyType getDistributionType() {
return distributionType;
}
public void setDistributionType(UncertaintyType distributionType) {
this.distributionType = distributionType;
}
public Double getParameter1Value() {
return parameter1Value;
}
public void setParameter1Value(Double parameter1Value) {
this.parameter1Value = parameter1Value;
}
public String getParameter1Formula() {
return parameter1Formula;
}
public void setParameter1Formula(String parameter1Formula) {
this.parameter1Formula = parameter1Formula;
}
public Double getParameter2Value() {
return parameter2Value;
}
public void setParameter2Value(Double parameter2Value) {
this.parameter2Value = parameter2Value;
}
public String getParameter2Formula() {
return parameter2Formula;
}
public void setParameter2Formula(String parameter2Formula) {
this.parameter2Formula = parameter2Formula;
}
public Double getParameter3Value() {
return parameter3Value;
}
public void setParameter3Value(Double parameter3Value) {
this.parameter3Value = parameter3Value;
}
public String getParameter3Formula() {
return parameter3Formula;
}
public void setParameter3Formula(String parameter3Formula) {
this.parameter3Formula = parameter3Formula;
}
/**
* Scales the distribution parameters by the given factor. This multiplies
* every distribution parameter with the given factor. Except for the
* geometric standard deviation in log-normal distributions as this
* parameter is scale independent.
*/
public void scale(double factor) {
if (parameter1Value != null)
parameter1Value = factor * parameter1Value;
if (parameter1Formula != null)
parameter1Formula = factor + " * (" + parameter1Formula + ")";
if (distributionType != UncertaintyType.LOG_NORMAL) {
if (parameter2Value != null)
parameter2Value = factor * parameter2Value;
if (parameter2Formula != null)
parameter2Formula = factor + " * (" + parameter2Formula + ")";
}
if (parameter3Value != null)
parameter3Value = factor * parameter3Value;
if (parameter3Formula != null)
parameter3Formula = factor + " * (" + parameter3Formula + ")";
}
@Override
public int hashCode() {
return Objects.hash(distributionType, parameter1Formula,
parameter1Value, parameter2Formula, parameter2Value,
parameter3Formula, parameter3Value);
}
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj == null)
return false;
if (!Objects.equals(this.getClass(), obj.getClass()))
return false;
Uncertainty other = (Uncertainty) obj;
if (this.distributionType != other.distributionType)
return false;
//@formatter:off
return Objects.equals(this.parameter1Value, other.parameter1Value)
&& Objects.equals(this.parameter2Value, other.parameter2Value)
&& Objects.equals(this.parameter3Value, other.parameter3Value)
&& Objects.equals(this.parameter1Formula, other.parameter1Formula)
&& Objects.equals(this.parameter2Formula, other.parameter2Formula)
&& Objects.equals(this.parameter3Formula, other.parameter3Formula);
//@formatter:on
}
}