package infosapient.system;
/*
* Copyright (c) 2001, Workplace Performance Tools, All Rights Reserved.
* License to use this program is provided under the COMMON PUBLIC LICENSE 0.5
* THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE
* ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
*/
import java.rmi.server.ObjID;
/**
* Class FzyGaussian builds a fuzzy set surface based on the classic Gaussian
* function rather than a sigmoidal function.
* <code> f(x) = e^(-K(cp - x)^2) </code>
* where K = width factor
* cp = central point of the curve
* Slope of membership of this function goes to zero very quickly.
* To be useful, values of k should range from .9 to 5.0.
* @author Michael McConnell
* @version $Revision: 1.1.1.1 $
* @package org.wpt.infosapient.system
*/
public class FzyGaussian extends FzySCurve {
static final long serialVersionUID = -5425204130702652529L;
public FzyGaussian() {
membership = new double[VECMAX];
domain = new double[VECMAX];
setID(new ObjID());
}
/**
* Constructor for creating a fuzzy set using a gaussian function.
* <p><b><i>NOTE: You cannot create a shouldered set using a gaussian function. Nor can you specify the low and high domain as these are calculated.</i></b></p>
* @param FzyAttribute - the owning attribute for this set
* @param double - center (the center of the set (aka 100% membership))
* @param kfactor - the width factor to be used in the construction. Useful values should range from .9 to 5.0.
* Cannot be <= zero.
* @throws FzySystemException
*/
public FzyGaussian(FzyAttribute fa, double center, double kFactor)
throws FzySystemException {
this();
setAttribute(fa);
addObserver(fa);
if (kFactor <= 0)
throw new FzySystemException(
" Width factor for "
+ "Gaussian set cannot be less than or equal"
+ " to zero. ");
setLowDomain(center * 0.75);
setHighDomain(center * 1.25);
setCmpMembership(center);
initializeDomain(getLowDomain(), getHighDomain());
double delta = getHighDomain() - getLowDomain();
synchronized (membership) {
for (int inx = 0; inx < VECMAX; inx++) {
double scalar = getLowDomain() * (double) inx / (VECMAX - 1) * delta;
double gausVal = kFactor * Math.pow((center - scalar), 2.0);
membership[inx] = Math.exp(gausVal);
}
}
}
/**
* Method for Cloneable interface -- provides a deep copy of the current
* set, EXCEPT the hedges.
* @return Object the new FzyGaussian cloned.
*/
public Object clone() {
FzyGaussian aSet = new FzyGaussian();
aSet.setName(this.getName());
aSet.setAttribute(this.getAttribute());
aSet.setLowDomain(this.getLowDomain());
aSet.setHighDomain(this.getHighDomain());
aSet.setCmpMembership(this.getCmpMembership());
aSet.setLowInflexionPt( this.getLowDomain(), this.getCmpMembership());
aSet.setHighInflexionPt(this.getHighDomain(), this.getCmpMembership());
for (int i = 0; i < this.VECMAX; i++) {
aSet.setMembership(this.membership[i], i);
aSet.setDomain(this.domain[i], i);
}
return (Object) aSet;
}
public void save(int ntabs){}
/**
* Used to provide a text description of this fuzzy set.
*/
public String toString() {
if (super.getName() == null) return typeAsString();
return super.getName();
}
public String typeAsString() {
return "Gaussian Curve";
}
}