![JAR search and dependency download from the Maven repository](/logo.png)
com.enterprisemath.math.probability.FrequencyDistribution Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of em-math Show documentation
Show all versions of em-math Show documentation
Advanced mathematical algorithms.
The newest version!
package com.enterprisemath.math.probability;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import com.enterprisemath.utils.DomainUtils;
import com.enterprisemath.utils.ValidationUtils;
/**
* Frequency distribution over the given space.
*
* @author radek.hecl
*
* @param observation type
*/
public class FrequencyDistribution implements ProbabilityDistribution {
/**
* Builder object.
*
* @param observation type
*/
public static class Builder {
/**
* Observation frequencies. Can be both absolute or relative, because these gets normalized.
*/
private Map frequencies = new HashMap();
/**
* Sets frequency of the specified observation.
*
* @param observation observation
* @param frequency frequency
* @return this instance
*/
public Builder setFrequency(T observation, double frequency) {
frequencies.put(observation, frequency);
return this;
}
/**
* Adds frequency of the specified observation.
*
* @param observation observation
* @param frequency frequency
* @return this instance
*/
public Builder addFrequency(T observation, double frequency) {
if (!frequencies.containsKey(observation)) {
frequencies.put(observation, frequency);
}
else {
frequencies.put(observation, frequencies.get(observation) + frequency);
}
return this;
}
/**
* Creates the result object.
*
* @return created object
*/
public FrequencyDistribution build() {
return new FrequencyDistribution(this);
}
}
/**
* Object for generating random values.
*/
private static final SecureRandom random = new SecureRandom();
/**
* Probabilities for each observation.
*/
private Map probabilities;
/**
* Cumulative function. This is internally used to generate random observations.
*/
private SortedMap cumulative;
/**
* Creates new instance.
*
* @param builder builder object
*/
public FrequencyDistribution(Builder builder) {
probabilities = DomainUtils.softCopyMap(builder.frequencies);
guardInvariants();
double sum = 0;
for (T obs : probabilities.keySet()) {
sum += probabilities.get(obs);
}
for (T obs : probabilities.keySet()) {
probabilities.put(obs, probabilities.get(obs) / sum);
}
}
/**
* Guards this object to be consistent. Throws exception if this is not the case.
*/
private void guardInvariants() {
ValidationUtils.guardNotNullMap(probabilities, "probabilities cannot have null element");
ValidationUtils.guardPositiveInt(probabilities.keySet().size(), "at least 1 observation must be defined");
for (T obs : probabilities.keySet()) {
ValidationUtils.guardPositiveDouble(probabilities.get(obs),
"observation must have positive frequency: observation = " + obs);
}
}
@Override
public double getValue(T x) {
if (probabilities.containsKey(x)) {
return probabilities.get(x);
}
return 0;
}
@Override
public double getLnValue(T x) {
if (probabilities.containsKey(x)) {
return Math.log(probabilities.get(x));
}
return Double.NEGATIVE_INFINITY;
}
@Override
public synchronized T generateRandom() {
if (cumulative == null) {
// calculate cumulative function
cumulative = new TreeMap();
double cml = 0;
for (T obs : probabilities.keySet()) {
cml = cml + probabilities.get(obs);
cumulative.put(cml, obs);
}
}
double r = random.nextDouble();
for (Double d : cumulative.keySet()) {
if (r < d) {
return cumulative.get(d);
}
}
throw new RuntimeException("error in source code, fix code");
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy