gov.sandia.cognition.statistics.DefaultDistributionParameter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gov-sandia-cognition-learning-core Show documentation
Show all versions of gov-sandia-cognition-learning-core Show documentation
Algorithms and components for machine learning and statistics.
The newest version!
/*
* File: DefaultDistributionParameter.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright Mar 1, 2010, Sandia Corporation.
* Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
* license for use of this work by or on behalf of the U.S. Government.
* Export of this program may require a license from the United States
* Government. See CopyrightHistory.txt for complete details.
*
*/
package gov.sandia.cognition.statistics;
import gov.sandia.cognition.util.AbstractNamed;
import gov.sandia.cognition.util.ObjectUtil;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
/**
* Default implementation of DistributionParameter using introspection.
* @param
* Type of parameter of the conditional distribution.
* @param
* Type of parameterized distribution that generates observations.
* @author Kevin R. Dixon
* @since 3.0
*/
public class DefaultDistributionParameter>
extends AbstractNamed
implements DistributionParameter
{
/**
* Distribution from which to pull the parameters.
*/
protected ConditionalType conditionalDistribution;
/**
* Setter for the parameter, the read method.
*/
transient protected Method parameterSetter;
/**
* Getter for the parameter, the write method.
*/
transient protected Method parameterGetter;
/**
* Name of the mean property, {@value}.
*/
public static final String MEAN_NAME = "mean";
/**
* Setter for the mean, {@value}.
*/
public static final String MEAN_SETTER = "setMean";
/**
* Getter for the mean, {@value}.
*/
public static final String MEAN_GETTER = "getMean";
/**
* Creates a new instance of DefaultDistributionParameter
* @param conditionalDistribution
* Distribution from which to pull the parameters.
* @param parameterName
* Name of the parameter
*/
public DefaultDistributionParameter(
final ConditionalType conditionalDistribution,
final String parameterName )
{
super( parameterName );
this.setConditionalDistribution(conditionalDistribution);
}
/**
* Creates a new instance of DefaultDistributionParameter
* @param conditionalDistribution
* Distribution from which to pull the parameters.
* @param descriptor
* PropertyDescriptor from the Introspector that has a setter and a getter.
*/
public DefaultDistributionParameter(
final ConditionalType conditionalDistribution,
final PropertyDescriptor descriptor )
{
this( conditionalDistribution, descriptor.getName() );
this.parameterGetter = descriptor.getReadMethod();
this.parameterSetter = descriptor.getWriteMethod();
}
@Override
public DefaultDistributionParameter clone()
{
@SuppressWarnings("unchecked")
DefaultDistributionParameter clone =
(DefaultDistributionParameter) super.clone();
clone.setConditionalDistribution(
ObjectUtil.cloneSafe(this.getConditionalDistribution() ) );
return clone;
}
/**
* Assigns the getter and setter from the given conditionalDistribution and parameter
* name.
* @param conditionalDistribution
* Distribution from which to pull the parameters.
* @param parameterName
* Name of the parameter
*/
protected void assignParameterMethods(
final Distribution> conditionalDistribution,
final String parameterName )
{
this.parameterGetter = null;
this.parameterSetter = null;
// Mean is a special case...
// Note: We can't use BeanInfo and Introspection on PropertyDescriptor
// because the signature of the getters and setters could be
// inconsistent. For example, a class could have a method of
// "Double getMean()", but the setter might be "void setMean(double)".
// Because the getter returns Double, but the setter takes a double,
// the Bean Introspection is too clever and doesn't consider them
// as getters and setters for the same property. Thus, we have to
// include our little hack below.
if( parameterName.equals( MEAN_NAME ) )
{
for( Method method : conditionalDistribution.getClass().getMethods() )
{
String methodString = method.getName();
if( methodString.contains( MEAN_GETTER ) )
{
this.parameterGetter = method;
}
else if( methodString.contains( MEAN_SETTER ) )
{
this.parameterSetter = method;
}
}
}
else
{
try
{
BeanInfo beaninfo =
Introspector.getBeanInfo(conditionalDistribution.getClass());
for (PropertyDescriptor descriptor : beaninfo.getPropertyDescriptors())
{
String propertyName = descriptor.getName();
if (propertyName.equals(parameterName))
{
this.parameterGetter = descriptor.getReadMethod();
this.parameterSetter = descriptor.getWriteMethod();
break;
}
}
}
catch (IntrospectionException ex)
{
throw new RuntimeException( ex );
}
}
if( this.parameterGetter == null )
{
throw new IllegalArgumentException(
"Could not find getter: " + parameterName + " in class " + this.getConditionalDistribution() );
}
if( this.parameterSetter == null )
{
throw new IllegalArgumentException(
"Could not find setter: " + parameterName + " in class " + this.getConditionalDistribution() );
}
}
@SuppressWarnings("unchecked")
@Override
public ParameterType getValue()
{
ParameterType retval = null;
try
{
if( this.parameterGetter == null )
{
this.assignParameterMethods(
this.getConditionalDistribution(), this.getName() );
}
retval = (ParameterType) this.parameterGetter.invoke(
this.getConditionalDistribution());
}
catch (Exception e)
{
throw new RuntimeException(e);
}
return retval;
}
@Override
public void setValue(
final ParameterType value )
{
try
{
if( this.parameterGetter == null )
{
this.assignParameterMethods(
this.getConditionalDistribution(), this.getName() );
}
this.parameterSetter.invoke( this.getConditionalDistribution(), value );
}
catch (Exception e)
{
throw new RuntimeException( e );
}
}
@Override
public ConditionalType getConditionalDistribution()
{
return this.conditionalDistribution;
}
/**
* Setter for conditionalDistribution
* @param conditionalDistribution
* Conditional conditionalDistribution associated with the parameter.
*/
protected void setConditionalDistribution(
final ConditionalType conditionalDistribution)
{
this.conditionalDistribution = conditionalDistribution;
}
@Override
public void setName(
final String name)
{
this.parameterGetter = null;
this.parameterSetter = null;
super.setName(name);
}
}