Process.java
package hierarchicalinterpolation.control;
import fuzzy.FuzzyNumber;
import fuzzy.IncompatibleFuzzyNumberTypeException;
import fuzzy.TrapezoidalFuzzyNumber;
import fuzzy.TriangularFuzzyNumber;
import hierarchicalinterpolation.model.Observation;
import hierarchicalinterpolation.model.Rule;
import hierarchicalinterpolation.model.RuleBase;
import hierarchicalinterpolation.model.RuleComparator;
import huang.PrintfFormat;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: rrd09
* Date: 28/07/11
* Time: 14:17
* To change this template use File | Settings | File Templates.
*/
public class Process {
private boolean verbose = true;
@Deprecated
public static float getDelta(FuzzyNumber aStar, FuzzyNumber a1, FuzzyNumber a2) {
return Math.abs((a1.getRepresentativeValue() - aStar.getRepresentativeValue()) / (a1.getRepresentativeValue() - a2.getRepresentativeValue()));
}
public static float[][] getNormalisedTermWeights(Observation observation, Rule[] rules, int missingIndex) {
float[][] termWeights = calculateTermWeights(observation, rules, missingIndex);
float wSum = 0;
for (int i = 0; i < observation.getNumberOfAntecedents(); i++) {
if (i != missingIndex) {
wSum = 0;
for (int j = 0; j < rules.length; j++) {
wSum += termWeights[j][i];
}
for (int j = 0; j < rules.length; j++) {
termWeights[j][i] = termWeights[j][i] / wSum;
//System.out.println("A*" + i + "NormlisedtermWeights " + ":" + termWeights[j][i]);
}
}
}
if (missingIndex < observation.getNumberOfAntecedents()) {
wSum = 0;
for (int j = 0; j < rules.length; j++) {
wSum += termWeights[j][observation.getNumberOfAntecedents()];
}
for (int j = 0; j < rules.length; j++) {
termWeights[j][observation.getNumberOfAntecedents()] = termWeights[j][observation.getNumberOfAntecedents()] / wSum;
//System.out.println("B*" + "NormlisedtermWeights to B" + j + ":" + termWeights[j][observation.getNumberOfAntecedents()]);
}
}
//System.out.println("Normalised Weights:");
//printArrays(termWeights);
return termWeights;
}
public static float[][] calculateTermWeights(Observation observation, Rule[] rules, int missingIndex) {
//termWeights is a N*(K+1) matrix of N rules, and K antecedents + 1 consequence
float[][] termWeights = new float[rules.length][observation.getAntecedents().length + 1];
for (int i = 0; i < rules.length; i++) {
for (int j = 0; j < rules[i].getAntecedents().length; j++) {
if (j != missingIndex) {
// System.out.println("rules" + i + "Antecedent" + j + rules[i].getAntecedent(j).toStringInt() + " vs " + "observation.Antecedent" + j + observation.getAntecedent(j).toStringInt());
float distance = rules[i].getAntecedent(j).absDistanceTo(observation.getAntecedent(j));
termWeights[i][j] = 1f / distance;
//System.out.println("A*" + j + "termWeights to R" + i + j + ":" + termWeights[i][j]);
}
}
if (missingIndex < observation.getNumberOfAntecedents()) {
termWeights[i][observation.getNumberOfAntecedents()] = 1f / rules[i].getConsequence().absDistanceTo(observation.getConsequence());
//System.out.println("B*" + "termWeights to B" + i + ":" + termWeights[i][observation.getNumberOfAntecedents()]);
}
}
//System.out.println("Raw Term Weights:");
//printArrays(termWeights);
return termWeights;
}
public static Rule getIntermediateFuzzyRule(Rule[] rules, float[][] normalisedWeights, int missingIndex)
throws IllegalAccessException, InstantiationException {
float[] points;
Rule intermediateFuzzyRule = new Rule(rules[0]);
for (int i = 0; i < rules[0].getNumberOfAntecedents(); i++) {
if (i != missingIndex) {
points = new float[rules[0].getAntecedent(i).getPoints().length];
for (int j = 0; j < rules.length; j++) {
for (int k = 0; k < points.length; k++) {
points[k] = points[k] + normalisedWeights[j][i] * rules[j].getAntecedent(i).getPoint(k);
}
}
FuzzyNumber intermediateFuzzyTerm = rules[0].getAntecedent(i).getClass().newInstance();
intermediateFuzzyTerm.setPoints(points);
intermediateFuzzyRule.setAntecedent(i, intermediateFuzzyTerm);
System.out.println("intermediate A''" + i + ":" + intermediateFuzzyRule.getAntecedent(i));
}
}
if (missingIndex < rules[0].getNumberOfAntecedents()) {
points = new float[rules[0].getConsequence().getPoints().length];
for (int j = 0; j < rules.length; j++) {
for (int k = 0; k < points.length; k++) {
points[k] = points[k] + normalisedWeights[j][rules[0].getNumberOfAntecedents()] *
rules[j].getConsequence().getPoint(k);
}
}
FuzzyNumber intermediateConsequence = rules[0].getConsequence().getClass().newInstance();
intermediateConsequence.setPoints(points);
intermediateFuzzyRule.setConsequence(intermediateConsequence);
System.out.println("intermediate B''" + intermediateFuzzyRule.getConsequence());
}
return intermediateFuzzyRule;
}
@Deprecated
public static FuzzyNumber getIntermediateFuzzyTerm(FuzzyNumber a1, FuzzyNumber a2, float delta)
throws IncompatibleFuzzyNumberTypeException {
float[] points = new float[a1.getPoints().length];
for (int i = 0; i < points.length; i++) {
points[i] = (1 - delta) * a1.getPoints()[i] + delta * a2.getPoints()[i];
}
if (a1 instanceof TriangularFuzzyNumber) {
return new TriangularFuzzyNumber(points);
} else if (a1 instanceof TrapezoidalFuzzyNumber) {
return new TrapezoidalFuzzyNumber(points);
} else {
throw new IncompatibleFuzzyNumberTypeException();
}
}
public static float getConsequenceScaleRate(float scaleRatio, float sB, float sT, FuzzyNumber fuzzyNumber) throws Exception {
/*if (fuzzyNumber instanceof TriangularFuzzyNumber) {
//TODO: Copy back the triangular function, check again later
return 0;
} else if (fuzzyNumber instanceof TrapezoidalFuzzyNumber) {*/
float rB = ((TrapezoidalFuzzyNumber) fuzzyNumber).getTopBottomSupportRatio();
if ((sT >= sB) && (sB >= 0)) {
//original equation is : sT = sB * (scaleRatio - scaleRatio * rB + rB) / rB
//which was transformed from ((sT / sB) * rB - rB) / (1 - rB) = scaleRatio
//where scaleRatio is calculated according the A' and A*
return sB * scaleRatio / rB - sB * scaleRatio + sB;
} else if ((sB >= sT) && (sT >= 0)) {
return sB * scaleRatio;
} else {
throw new Exception("Unsupported Scale Rate");
}
/*}
return 0;*/
}
public static float getScaleRate(FuzzyNumber aDash, FuzzyNumber aStar) throws Exception {
if (aDash instanceof TriangularFuzzyNumber) {
return (aStar.getPoints()[2] - aStar.getPoints()[0]) /
(aDash.getPoints()[2] - aDash.getPoints()[0]);
} else if (aDash instanceof TrapezoidalFuzzyNumber) {
if ((((TrapezoidalFuzzyNumber) aStar).getTopBottomSupportRatio() >=
((TrapezoidalFuzzyNumber) aDash).getTopBottomSupportRatio()) &&
(((TrapezoidalFuzzyNumber) aDash).getTopBottomSupportRatio() >= 0)) {
return ((aStar.getPoints()[2] - aStar.getPoints()[1]) / (aStar.getPoints()[3] - aStar.getPoints()[0]) -
(aDash.getPoints()[2] - aDash.getPoints()[1]) / (aDash.getPoints()[3] - aDash.getPoints()[0])) /
(1 - (aDash.getPoints()[2] - aDash.getPoints()[1]) / (aDash.getPoints()[3] - aDash.getPoints()[0]));
} else if ((((TrapezoidalFuzzyNumber) aDash).getTopBottomSupportRatio() >=
((TrapezoidalFuzzyNumber) aStar).getTopBottomSupportRatio()) &&
(((TrapezoidalFuzzyNumber) aStar).getTopBottomSupportRatio() >= 0)) {
return ((aStar.getPoints()[2] - aStar.getPoints()[1]) / (aStar.getPoints()[3] - aStar.getPoints()[0]) -
(aDash.getPoints()[2] - aDash.getPoints()[1]) / (aDash.getPoints()[3] - aDash.getPoints()[0])) /
((aDash.getPoints()[2] - aDash.getPoints()[1]) / (aDash.getPoints()[3] - aDash.getPoints()[0]));
} else {
throw new Exception("Unsupported Scale Rate");
}
}
return 0;
}
public static float getMoveRatio(FuzzyNumber aDashScaled, FuzzyNumber aStar) throws Exception {
float moveRatio = 0;
if (aDashScaled instanceof TriangularFuzzyNumber) {
if (aStar.getPoints()[0] >= aDashScaled.getPoints()[0]) {
moveRatio = (aStar.getPoints()[0] - aDashScaled.getPoints()[0]) * 3 /
(aDashScaled.getPoints()[1] - aDashScaled.getPoints()[0]);
if ((moveRatio < 0) || (moveRatio > 1))
throw new Exception("Move Ratio (" + moveRatio + ") cannot exceed [0,1]");
} else {
moveRatio = (aStar.getPoints()[0] - aDashScaled.getPoints()[0]) * 3 /
(aDashScaled.getPoints()[2] - aDashScaled.getPoints()[1]);
if ((moveRatio > 0) || (moveRatio < -1))
throw new Exception("Move Ratio (" + moveRatio + ") cannot exceed [-1,0]");
}
} else if (aDashScaled instanceof TrapezoidalFuzzyNumber) {
if (aStar.getPoints()[0] >= aDashScaled.getPoints()[0]) {
moveRatio = (aStar.getPoints()[0] - aDashScaled.getPoints()[0]) * 3 /
(aDashScaled.getPoints()[1] - aDashScaled.getPoints()[0]);
if ((moveRatio < 0) || (moveRatio > 1))
throw new Exception("Move Ratio (" + moveRatio + ") cannot exceed [0,1]");
} else {
moveRatio = (aStar.getPoints()[0] - aDashScaled.getPoints()[0]) * 3 /
(aDashScaled.getPoints()[3] - aDashScaled.getPoints()[2]);
if ((moveRatio > 0) || (moveRatio < -1))
throw new Exception("Move Ratio (" + moveRatio + ") cannot exceed [-1,0]");
}
}
return moveRatio;
}
public static float getBottomScaleRate(FuzzyNumber aDash, FuzzyNumber aStar) {
return (aStar.getPoints()[3] - aStar.getPoints()[0]) /
(aDash.getPoints()[3] - aDash.getPoints()[0]);
}
public static float getTopScaleRate(FuzzyNumber aDash, FuzzyNumber aStar) {
return (aStar.getPoints()[2] - aStar.getPoints()[1]) /
(aDash.getPoints()[2] - aDash.getPoints()[1]);
}
public static Rule shift(Rule intermediateRule, Observation observation, int missingIndex) {
Rule shiftedIntermediateRule = new Rule(intermediateRule);
float delta = 0, deltaSum = 0;
if (missingIndex >= intermediateRule.getNumberOfAntecedents()) {
//forward
for (int i = 0; i < intermediateRule.getNumberOfAntecedents(); i++) {
float distance = observation.getAntecedent(i).distanceTo(intermediateRule.getAntecedent(i));
delta = distance /
(intermediateRule.getMaxAntecedentRanges()[i] - intermediateRule.getMinAntecedentRanges()[i]);
shiftedIntermediateRule.setAntecedent(i, intermediateRule.getAntecedent(i).adds(delta *
(intermediateRule.getMaxAntecedentRanges()[i] - intermediateRule.getMinAntecedentRanges()[i])));
deltaSum += delta;
System.out.println("Delta A" + i + " " + delta);
}
delta = deltaSum / intermediateRule.getNumberOfAntecedents();
System.out.println("Delta B " + delta);
shiftedIntermediateRule.setConsequence(intermediateRule.getConsequence().adds(
delta * (intermediateRule.getMaxConsequenceRange() - intermediateRule.getMinConsequenceRange())));
System.out.println("(f)shifted B'" + ":" + shiftedIntermediateRule.getConsequence() + " " + shiftedIntermediateRule.getConsequence().getRepresentativeValue());
} else {
for (int i = 0; i < intermediateRule.getNumberOfAntecedents(); i++) {
if (i != missingIndex) {
delta = observation.getAntecedent(i).distanceTo(intermediateRule.getAntecedent(i)) /
(intermediateRule.getMaxAntecedentRanges()[i] - intermediateRule.getMinAntecedentRanges()[i]);
shiftedIntermediateRule.setAntecedent(i, intermediateRule.getAntecedent(i).adds(delta *
(intermediateRule.getMaxAntecedentRanges()[i] - intermediateRule.getMinAntecedentRanges()[i])));
System.out.println("shifted A'" + i + ":" + shiftedIntermediateRule.getAntecedent(i));
deltaSum += delta;
System.out.println("Delta A" + i + " " + delta);
}
}
delta = observation.getConsequence().distanceTo(intermediateRule.getConsequence()) /
(intermediateRule.getMaxConsequenceRange() - intermediateRule.getMinConsequenceRange());
System.out.println("Delta B " + delta);
shiftedIntermediateRule.setConsequence(intermediateRule.getConsequence().adds(delta *
(intermediateRule.getMaxConsequenceRange() - intermediateRule.getMinConsequenceRange())));
System.out.println("(b)shifted B'" + ":" + shiftedIntermediateRule.getConsequence() + " " + shiftedIntermediateRule.getConsequence().getRepresentativeValue());
delta = delta * intermediateRule.getNumberOfAntecedents() - deltaSum;
System.out.println("Delta A" + missingIndex + " " + delta);
shiftedIntermediateRule.setAntecedent(missingIndex, intermediateRule.getAntecedent(missingIndex).adds(
delta * (intermediateRule.getMaxAntecedentRanges()[missingIndex] -
intermediateRule.getMinAntecedentRanges()[missingIndex])));
System.out.println("shifted A'" + missingIndex + ":" + shiftedIntermediateRule.getAntecedent(missingIndex));
}
return shiftedIntermediateRule;
}
public static TriangularFuzzyNumber scale(TriangularFuzzyNumber fuzzyNumber, float scaleRate) throws Exception {
if (scaleRate < 0) throw new Exception("Scale Rate (" + scaleRate + ") cannot be less than 0");
double newLeftShoulder = (fuzzyNumber.getLeftShoulder() * (1 + 2 * scaleRate) +
fuzzyNumber.getCentroid() * (1 - scaleRate) +
fuzzyNumber.getRightShoulder() * (1 - scaleRate)) / 3;
double newCentroid = (fuzzyNumber.getLeftShoulder() * (1 - scaleRate) +
fuzzyNumber.getCentroid() * (1 + 2 * scaleRate) +
fuzzyNumber.getRightShoulder() * (1 - scaleRate)) / 3;
double newRightShoulder = (fuzzyNumber.getLeftShoulder() * (1 - scaleRate) +
fuzzyNumber.getCentroid() * (1 - scaleRate) +
fuzzyNumber.getRightShoulder() * (1 + 2 * scaleRate)) / 3;
return new TriangularFuzzyNumber(newLeftShoulder, newCentroid, newRightShoulder);
}
public static TrapezoidalFuzzyNumber scale(TrapezoidalFuzzyNumber fuzzyNumber, float sB, float sT) throws Exception {
float a0 = fuzzyNumber.getPoints()[0];
float a1 = fuzzyNumber.getPoints()[1];
float a2 = fuzzyNumber.getPoints()[2];
float a3 = fuzzyNumber.getPoints()[3];
/* if (scaleRate < 0)
// scaleRate=-scaleRate;
throw new Exception("Scale Rate (" + scaleRate + ") cannot be less than 0");*/
float A = (2 * a0 + a1 + a2 + 2 * a3) / 6;
float B = 6 * (a1 + a3 - a0 - a2);
float C = 2 * sB * (a3 - a0);
float D = sT * (a2 - a1);
float newLeftShoulder = A - (C * (2 * a1 + a3 - 2 * a0 - a2) - D * (a1 + a2 - a0 - a3)) / B;
float newLeftCentroid = A - (C * (a0 + a3 - a1 - a2) - D * (5 * a0 + a2 - 5 * a1 - a3)) / B;
float newRightCentroid = A - (C * (a0 + a3 - a1 - a2) - D * (a1 + 5 * a3 - a0 - 5 * a2)) / B;
float newRightShoulder = A - (C * (a0 + 2 * a2 - a1 - 2 * a3) - D * (a1 + a2 - a0 - a3)) / B;
return new TrapezoidalFuzzyNumber(newLeftShoulder, newLeftCentroid, newRightCentroid, newRightShoulder);
}
/*public static float getMoveRatio(FuzzyNumber aDashScaled, FuzzyNumber aStar) throws Exception {
float moveRatio;
if (aDashScaled.getLeftShoulder() >= aStar.getLeftShoulder()) {
moveRatio = (aDashScaled.getLeftCentroid() - aStar.getLeftShoulder()) * 3 /
(aStar.getLeftCentroid() - aStar.getLeftShoulder());
if ((moveRatio < 0) || (moveRatio > 1))
throw new Exception("Move Ratio (" + moveRatio + ") cannot exceed [0,1]");
} else {
moveRatio = (aDashScaled.getLeftShoulder() - aStar.getLeftShoulder()) * 3 /
(aStar.getRightShoulder() - aStar.getRightCentroid());
if ((moveRatio > 0) || (moveRatio < -1))
throw new Exception("Move Ratio (" + moveRatio + ") cannot exceed [-1,0]");
}
return moveRatio;
}*/
public static TrapezoidalFuzzyNumber move(TrapezoidalFuzzyNumber fuzzyNumber, float moveRatio) {
float moveRate = (moveRatio >= 0) ?
moveRatio * (fuzzyNumber.getPoints()[1] - fuzzyNumber.getPoints()[0]) / 3 :
moveRatio * (fuzzyNumber.getPoints()[3] - fuzzyNumber.getPoints()[2]) / 3;
return new TrapezoidalFuzzyNumber(fuzzyNumber.getPoints()[0] + moveRate,
fuzzyNumber.getPoints()[1] - 2 * moveRate,
fuzzyNumber.getPoints()[2] - 2 * moveRate,
fuzzyNumber.getPoints()[3] + moveRate);
}
public static TriangularFuzzyNumber move(TriangularFuzzyNumber fuzzyNumber, float moveRatio) {
float moveRate = (moveRatio >= 0) ?
moveRatio * (fuzzyNumber.getPoints()[1] - fuzzyNumber.getPoints()[0]) / 3 :
moveRatio * (fuzzyNumber.getPoints()[2] - fuzzyNumber.getPoints()[1]) / 3;
return new TriangularFuzzyNumber(fuzzyNumber.getLeftShoulder() + moveRate,
fuzzyNumber.getCentroid() - 2 * moveRate,
fuzzyNumber.getRightShoulder() + moveRate);
}
public static Rule getIntermediateRule(Rule[] rules, Observation observation, int missingIndex)
throws InstantiationException, IllegalAccessException {
float[][] normalisedWeights = getNormalisedTermWeights(observation, rules, missingIndex);
Rule intermediateRule = getIntermediateFuzzyRule(rules, normalisedWeights, missingIndex);
if ((missingIndex >= 0) & (missingIndex < observation.getAntecedents().length)) {
//backward
float[] points = new float[rules[0].getAntecedent(missingIndex).getPoints().length];
float wSum = 0;
for (int i = 0; i < rules.length; i++) {
wSum = 0;
for (int j = 0; j < rules[0].getNumberOfAntecedents(); j++) {
if (j != missingIndex) {
wSum += normalisedWeights[i][j];
}
}
normalisedWeights[i][missingIndex] = normalisedWeights[i][rules[0].getNumberOfAntecedents()] *
rules[0].getNumberOfAntecedents() - wSum;
for (int k = 0; k < points.length; k++) {
points[k] = points[k] + normalisedWeights[i][missingIndex] * rules[i].getAntecedent(missingIndex).getPoint(k);
}
}
FuzzyNumber intermediateMissingAntecedent = rules[0].getAntecedent(missingIndex).getClass().newInstance();
intermediateMissingAntecedent.setPoints(points);
intermediateRule.setAntecedent(missingIndex, intermediateMissingAntecedent);
System.out.println("intermediate A''" + missingIndex + "'':" + intermediateRule.getAntecedents()[missingIndex ]);
} else {
//forward
float[] points = new float[rules[0].getConsequence().getPoints().length];
float wSum = 0;
for (int i = 0; i < rules.length; i++) {
wSum = 0;
for (int j = 0; j < rules[0].getNumberOfAntecedents(); j++) {
wSum += normalisedWeights[i][j];
}
normalisedWeights[i][rules[0].getNumberOfAntecedents()] = wSum / rules[0].getNumberOfAntecedents();
for (int k = 0; k < points.length; k++) {
points[k] = points[k] + normalisedWeights[i][rules[0].getNumberOfAntecedents()] * rules[i].getConsequence().getPoint(k);
}
}
FuzzyNumber intermediateConsequence = rules[0].getConsequence().getClass().newInstance();
intermediateConsequence.setPoints(points);
intermediateRule.setConsequence(intermediateConsequence);
System.out.println("intermediate B'':" + intermediateRule.getConsequence());
float consequenceWeightSum = 0;
for (int i = 0; i < rules.length; i++) {
float consequenceWeight = (float) (1/ Math.abs(intermediateConsequence.distanceTo(rules[i].getConsequence()) -0.092990205*15));
consequenceWeightSum += consequenceWeight;
}
for (int i = 0; i < rules.length; i++) {
float consequenceWeight2 = (float) (1/ Math.abs(intermediateConsequence.distanceTo(rules[i].getConsequence()) -0.092990205*15));
consequenceWeight2 = consequenceWeight2 / consequenceWeightSum;
System.out.print(consequenceWeight2 + "\t");
}
System.out.println();
}
System.out.println("Normalised Weights:");
printArrays(normalisedWeights);
Rule shiftedIntermediateRule = shift(intermediateRule, observation, missingIndex);
float consequenceWeightSum = 0;
for (int i = 0; i < rules.length; i++) {
float consequenceWeight = 1/ shiftedIntermediateRule.getConsequence().absDistanceTo(rules[i].getConsequence());
consequenceWeightSum += consequenceWeight;
}
for (int i = 0; i < rules.length; i++) {
float consequenceWeight2 = 1/ shiftedIntermediateRule.getConsequence().absDistanceTo(rules[i].getConsequence());
consequenceWeight2 = consequenceWeight2 / consequenceWeightSum;
System.out.print(consequenceWeight2 + "\t");
}
System.out.println();
return shiftedIntermediateRule;
}
@Deprecated
public static Rule getIntermediateRule(Rule rule1, Rule rule2, Observation observation, int dimensionToBeInterpolated) throws IncompatibleFuzzyNumberTypeException {
float deltaSum = 0;
float delta;
Rule intermediateRule = new Rule(rule1);
if ((dimensionToBeInterpolated >= 0) & (dimensionToBeInterpolated < observation.getAntecedents().length)) {
//backward
for (int i = 0; i < observation.getAntecedents().length; i++) {
if (i != dimensionToBeInterpolated) {
delta = getDelta(observation.getAntecedents()[i],
rule1.getAntecedents()[i],
rule2.getAntecedents()[i]);
System.out.println(i + "'th dimension delta:" + delta);
deltaSum = deltaSum + delta;
intermediateRule.getAntecedents()[i] =
getIntermediateFuzzyTerm(rule1.getAntecedents()[i], rule2.getAntecedents()[i], delta);
}
}
delta = getDelta(observation.getConsequence(),
rule1.getConsequence(),
rule2.getConsequence());
System.out.println("Consequence delta:" + delta);
intermediateRule.setConsequence(
getIntermediateFuzzyTerm(rule1.getConsequence(), rule2.getConsequence(), delta));
delta = delta * observation.getAntecedents().length - deltaSum;
System.out.println(dimensionToBeInterpolated + "'th antecedent delta:" + delta);
intermediateRule.getAntecedents()[dimensionToBeInterpolated] =
getIntermediateFuzzyTerm(
rule1.getAntecedents()[dimensionToBeInterpolated],
rule2.getAntecedents()[dimensionToBeInterpolated], delta);
} else {
//forward
for (int i = 0; i < observation.getAntecedents().length; i++) {
delta = getDelta(observation.getAntecedents()[i],
rule1.getAntecedents()[i],
rule2.getAntecedents()[i]);
System.out.println(i + "'th antecedent delta=" + delta);
deltaSum = deltaSum + delta;
intermediateRule.getAntecedents()[i] =
getIntermediateFuzzyTerm(rule1.getAntecedents()[i], rule2.getAntecedents()[i], delta);
}
delta = deltaSum / observation.getAntecedents().length;
System.out.println("Consequent delta=" + delta);
intermediateRule.setConsequence(
getIntermediateFuzzyTerm(rule1.getConsequence(), rule2.getConsequence(), delta));
}
// System.out.println("delta=" + delta);
for (int j = 0; j < intermediateRule.getAntecedents().length; j++) {
System.out.println("A" + j + "' antecedent = " + intermediateRule.getAntecedents()[j].toString());
}
System.out.println(" B'= " + intermediateRule.getConsequence().toString());
return intermediateRule;
}
public static Rule transform(Rule intermediateRule, Observation observation, int missingIndex) throws Exception {
if ((missingIndex >= 0) & (missingIndex < observation.getAntecedents().length)) {
if (intermediateRule.getAntecedent(missingIndex) instanceof TrapezoidalFuzzyNumber) {
return backwardInterpolation(new TrapezoidalFuzzyNumber(),
intermediateRule,
observation,
missingIndex);
} else {
return backwardInterpolation(new TriangularFuzzyNumber(),
intermediateRule,
observation,
missingIndex);
}
} else {
if (intermediateRule.getConsequence() instanceof TrapezoidalFuzzyNumber) {
return forwardInterpolation(new TrapezoidalFuzzyNumber(),
intermediateRule,
observation);
} else {
return forwardInterpolation(new TriangularFuzzyNumber(),
intermediateRule,
observation);
}
}
}
private static Rule forwardInterpolation(TriangularFuzzyNumber triangularFuzzyNumber,
Rule intermediateRule,
Observation observation) throws Exception {
//Rule scaledRule = new Rule(intermediateRule);
Rule transformedRule = new Rule(intermediateRule);
float s = 0, sSum = 0, m = 0, mSum = 0;
for (int i = 0; i < intermediateRule.getNumberOfAntecedents(); i++) {
s = getScaleRate(intermediateRule.getAntecedent(i), observation.getAntecedent(i));
System.out.println(i + "'th dimension: " + "s=" + s);
intermediateRule.setAntecedent(i, scale((TriangularFuzzyNumber) intermediateRule.getAntecedent(i), s));
System.out.println("scaled A" + i + "'':" + intermediateRule.getAntecedents()[i]);
sSum = sSum + s;
m = getMoveRatio(intermediateRule.getAntecedent(i), observation.getAntecedent(i));
System.out.println(i + "'th dimension: " + "m=" + m);
transformedRule.setAntecedent(i, move((TriangularFuzzyNumber) intermediateRule.getAntecedent(i), m));
mSum = mSum + m;
}
s = sSum / intermediateRule.getNumberOfAntecedents();
m = mSum / intermediateRule.getNumberOfAntecedents();
System.out.println("Consequence dimension: " + "s=" + s);
System.out.println("Consequence dimension: " + "m=" + m);
transformedRule.setConsequence(move(scale((TriangularFuzzyNumber) intermediateRule.getConsequence(), s), m));
return transformedRule;
}
private static Rule backwardInterpolation(TriangularFuzzyNumber triangularFuzzyNumber,
Rule intermediateRule,
Observation observation,
int missingIndex) throws Exception {
Rule transformedRule = new Rule(intermediateRule);
float s = 0, sSum = 0, m = 0, mSum = 0;
for (int i = 0; i < observation.getAntecedents().length; i++) {
if (i != missingIndex) {
s = getScaleRate(intermediateRule.getAntecedents()[i], observation.getAntecedents()[i]);
System.out.println(i + "'th dimension: " + "s=" + s);
intermediateRule.setAntecedent(i, scale((TriangularFuzzyNumber) intermediateRule.getAntecedent(i), s));
System.out.println("scaled A" + i + "'':" + intermediateRule.getAntecedents()[i]);
sSum = sSum + s;
m = getMoveRatio(intermediateRule.getAntecedent(i), observation.getAntecedent(i));
System.out.println(i + "'th dimension: " + "m=" + m);
transformedRule.setAntecedent(i, move((TriangularFuzzyNumber) intermediateRule.getAntecedent(i), m));
mSum = mSum + m;
}
}
s = getScaleRate(intermediateRule.getConsequence(), observation.getConsequence());
intermediateRule.setConsequence(scale((TriangularFuzzyNumber) intermediateRule.getConsequence(), s));
System.out.println("Consequence dimension: " + "s=" + s);
System.out.println("B'':" + intermediateRule.getConsequence());
m = getMoveRatio(intermediateRule.getConsequence(), observation.getConsequence());
transformedRule.setConsequence(move((TriangularFuzzyNumber) intermediateRule.getConsequence(), m));
System.out.println("Consequence dimension: " + "m=" + m);
s = s * observation.getAntecedents().length - sSum;
System.out.println(missingIndex + " dimension: " + "s=" + s);
m = m * observation.getAntecedents().length - mSum;
System.out.println(missingIndex + " dimension: " + "m=" + m);
transformedRule.getAntecedents()[missingIndex] = scale((TriangularFuzzyNumber) intermediateRule.getAntecedents()[missingIndex], s);
System.out.println("scaled A" + missingIndex + "''" + transformedRule.getAntecedents()[missingIndex].toString());
transformedRule.getAntecedents()[missingIndex] = move((TriangularFuzzyNumber) transformedRule.getAntecedents()[missingIndex], m);
System.out.println("Backward interpolation antecedent:" + missingIndex + transformedRule.getAntecedents()[missingIndex].toString());
return transformedRule;
}
private static Rule backwardInterpolation(TrapezoidalFuzzyNumber trapezoidalFuzzyNumber,
Rule intermediateRule,
Observation observation,
int missingIndex) throws Exception {
Rule scaledRule = new Rule(intermediateRule);
Rule transformedRule = new Rule(intermediateRule);
float sb = 0, st = 0, sbSum = 0, stSum = 0, scaleRatio = 0, scaleRatioSum = 0, m = 0, mSum = 0;
//backward
for (int i = 0; i < observation.getAntecedents().length; i++) {
if (i != missingIndex) {
sb = getBottomScaleRate(intermediateRule.getAntecedents()[i], observation.getAntecedents()[i]);
st = getTopScaleRate(intermediateRule.getAntecedents()[i], observation.getAntecedents()[i]);
scaleRatio = getScaleRate(intermediateRule.getAntecedents()[i], observation.getAntecedents()[i]);
System.out.println(i + "'th dimension: " + "sb=" + sb + "and " + " st=" + st);
System.out.println("scaleRatio A" + i + " = " + scaleRatio);
//intermediateRule.getAntecedents()[i] = scale(intermediateRule.getAntecedents()[i], sb, st);
scaledRule.getAntecedents()[i] = scale((TrapezoidalFuzzyNumber) intermediateRule.getAntecedent(i), sb, st);
System.out.println("A" + i + "'':" + scaledRule.getAntecedents()[i]);
sbSum = sbSum + sb;
stSum = stSum + st;
scaleRatioSum = scaleRatioSum + scaleRatio;
m = getMoveRatio(scaledRule.getAntecedents()[i], observation.getAntecedents()[i]);
System.out.println(i + "'th dimension: " + "m=" + m);
transformedRule.getAntecedents()[i] = move((TrapezoidalFuzzyNumber) scaledRule.getAntecedents()[i], m);
mSum = mSum + m;
}
}
sb = getBottomScaleRate(intermediateRule.getConsequence(), observation.getConsequence());
st = getTopScaleRate(intermediateRule.getConsequence(), observation.getConsequence());
scaleRatio = getScaleRate(intermediateRule.getConsequence(), observation.getConsequence());
scaledRule.setConsequence(scale((TrapezoidalFuzzyNumber) intermediateRule.getConsequence(), sb, st));
System.out.println("Consequence dimension: " + "sb=" + sb + "and " + " st=" + st);
System.out.println("Scaled B'':" + scaledRule.getConsequence());
System.out.println("B scaleRatio " + " = " + scaleRatio);
m = getMoveRatio(scaledRule.getConsequence(), observation.getConsequence());
transformedRule.setConsequence(move((TrapezoidalFuzzyNumber) scaledRule.getConsequence(), m));
System.out.println("Consequence dimension: " + "m=" + m);
sb = sb * observation.getAntecedents().length - sbSum;
st = st * observation.getAntecedents().length - stSum;
scaleRatio = scaleRatio * observation.getAntecedents().length - scaleRatioSum;
st = getConsequenceScaleRate(scaleRatio, sb, st, intermediateRule.getAntecedents()[missingIndex]);
System.out.println(missingIndex + " dimension: " + "sb=" + sb + "and " + " st=" + st);
System.out.println("A" + missingIndex + "scaleRatio " + " = " + scaleRatio);
m = m * observation.getAntecedents().length - mSum;
System.out.println(missingIndex + " dimension: " + "m=" + m);
scaledRule.setAntecedent(missingIndex, scale((TrapezoidalFuzzyNumber) intermediateRule.getAntecedents()[missingIndex], sb, st));
System.out.println("Scaled A" + missingIndex + "''" + scaledRule.getAntecedents()[missingIndex].toString());
transformedRule.setAntecedent(missingIndex, move((TrapezoidalFuzzyNumber) scaledRule.getAntecedents()[missingIndex], m));
System.out.println("Backward interpolation antecedent:" + "missingIndex " + transformedRule.getAntecedents()[missingIndex].toString());
return transformedRule;
}
private static Rule forwardInterpolation(TrapezoidalFuzzyNumber trapezoidalFuzzyNumber,
Rule intermediateRule,
Observation observation) throws Exception {
Rule scaledRule = new Rule(intermediateRule);
Rule transformedRule = new Rule(intermediateRule);
float sb = 0, st = 0, sbSum = 0, stSum = 0, scaleRatio = 0, scaleRatioSum = 0, m = 0, mSum = 0;
//forward
for (int i = 0; i < observation.getAntecedents().length; i++) {
//
sb = getBottomScaleRate(intermediateRule.getAntecedent(i), observation.getAntecedent(i));
st = getTopScaleRate(intermediateRule.getAntecedent(i), observation.getAntecedent(i));
scaleRatio = getScaleRate(intermediateRule.getAntecedent(i), observation.getAntecedent(i));
System.out.println(i + "'dimension:" + "sb=" + sb + "and " + " st=" + st);
System.out.println("scaleRatio " + i + " = " + scaleRatio);
scaledRule.setAntecedent(i, scale((TrapezoidalFuzzyNumber) intermediateRule.getAntecedent(i), sb, st));
System.out.println("A" + i + "''" + scaledRule.getAntecedent(i).toString());
sbSum = sbSum + sb;
stSum = stSum + st;
scaleRatioSum = scaleRatioSum + scaleRatio;
m = getMoveRatio(scaledRule.getAntecedent(i), observation.getAntecedent(i));
System.out.println(i + "'dimension:" + "m=" + m);
transformedRule.setAntecedent(i, move((TrapezoidalFuzzyNumber) scaledRule.getAntecedent(i), m));
System.out.println("A" + i + "*" + transformedRule.getAntecedent(i).toString());
mSum = mSum + m;
}
sb = sbSum / observation.getAntecedents().length;
st = stSum / observation.getAntecedents().length;
scaleRatio = scaleRatioSum / observation.getAntecedents().length;
st = getConsequenceScaleRate(scaleRatio, sb, st, intermediateRule.getConsequence());
System.out.println("Consequent dimension:" + "sb=" + sb + "and " + " st=" + st);
intermediateRule.setConsequence(scale((TrapezoidalFuzzyNumber) intermediateRule.getConsequence(), sb, st));
m = mSum / observation.getAntecedents().length;
System.out.println("Scaled B'':" + intermediateRule.getConsequence());
System.out.println("Consequent dimension: m=" + m);
transformedRule.setConsequence(move((TrapezoidalFuzzyNumber) intermediateRule.getConsequence(), m));
return transformedRule;
}
/*
if ((st >= sb) && (sb >= 0)) {
st = (st * (a2 - a1) / (sb * (a3 - a0)) - (a2 - a1) / (a3 - a0)) /
(1 - (a2 - a1) / (a3 - a0));
} else if ((sb >= st) && (st >= 0)) {
st = (st * (a2 - a1) / (sb * (a3 - a0)) - (a2 - a1) / (a3 - a0)) /
((a2 - a1) / (a3 - a0));
} else {
throw new Exception("Unsupported Scale Rate");
}
*/
@Deprecated
private Rule[] getClosestRules(FuzzyNumber subConsequence,
ArrayList<Rule> rules) {
Rule[] closestRules = new Rule[2];
float[] distances = new float[rules.size()];
for (int i = 0; i < rules.size(); i++) {
distances[i] = rules.get(i).getConsequence().distanceTo(subConsequence);
}
float minDistance1 = Float.MAX_VALUE;
int minIndex1 = 0;
float minDistance2 = Float.MAX_VALUE;
int minIndex2 = 0;
for (int i = 0; i < rules.size(); i++) {
if ((Math.abs(distances[i]) < minDistance1) & (distances[i] * distances[minIndex1] < 0)) {
minDistance2 = minDistance1;
minIndex2 = minIndex1;
minDistance1 = Math.abs(distances[i]);
minIndex1 = i;
} else if ((Math.abs(distances[i]) < minDistance2) & (distances[i] * distances[minIndex1] < 0)) {
minDistance2 = Math.abs(distances[i]);
minIndex2 = i;
}
}
closestRules[0] = rules.get(minIndex1).clone();
closestRules[1] = rules.get(minIndex2).clone();
return closestRules;
}
public static Rule[] getClosestRules(RuleBase ruleBase,
Observation observation,
int numberOfClosestRules,
boolean useWeightedConsequenceDistance) {
sortRuleBase(ruleBase, observation, useWeightedConsequenceDistance);
Rule[] closestRules = new Rule[numberOfClosestRules];
List<Rule> tempClosestRules = ruleBase.subList(0, numberOfClosestRules);
for (int i = 0; i < numberOfClosestRules; i++) {
closestRules[i] = tempClosestRules.get(i);
}
return closestRules;
/*
closestRules[0] = ruleBase.get(0).clone();
int currentRuleIndex = 1;
int startIndex = 1;
//boolean valid = true;
while (currentRuleIndex != numberOfClosestRules) {
for (int i = startIndex; i < ruleBase.size(); i++) {
Rule currentRule = ruleBase.get(i);
valid = true;
for (int j = 0; j < currentRule.getAntecedents().length; j++) {
if (observation.getAntecedents()[j] == null) {
valid = valid & (currentRule.getConsequence()
.distanceTo(observation.getConsequence()) *
closestRules[currentRuleIndex - 1].getConsequence()
.distanceTo(observation.getConsequence()) < 0);
} else {
valid = valid &
(currentRule.getAntecedents()[j]
.distanceTo(observation.getAntecedents()[j]) *
closestRules[currentRuleIndex - 1].getAntecedents()[j]
.distanceTo(observation.getAntecedents()[j]) < 0);
}
}
if (valid == true) {
closestRules[currentRuleIndex] = ruleBase.get(i).clone();
startIndex = i;
currentRuleIndex++;
i = ruleBase.size();
}
//startIndex = i;
}
//currentRuleIndex ++;
}
return closestRules;*/
}
public static void sortRuleBase(RuleBase ruleBase, Observation observation, boolean useWeightedConsequenceDistance) {
Collections.sort(ruleBase, new RuleComparator(observation, useWeightedConsequenceDistance));
}
public static void printRules(Rule[] rules) {
for (int i = 0; i < rules.length; i++) {
for (FuzzyNumber fuzzyNumber : rules[i].getAntecedents()) {
System.out.print(fuzzyNumber.toString() + "\t");
}
System.out.println(rules[i].getConsequence().toString());
}
}
public static void printRule(Rule rule) {
for (FuzzyNumber fuzzyNumber : rule.getAntecedents()) {
if (fuzzyNumber != null) {
System.out.print(fuzzyNumber.toString() + "\t");
} else {
System.out.print("(null, null, null)" + "\t");
}
}
if (rule.getConsequence() != null) {
System.out.println(rule.getConsequence().toString());
} else {
System.out.println("(null, null, null)");
}
}
public static void printRules(RuleBase ruleBase) {
for (int i = 0; i < ruleBase.size(); i++) {
for (FuzzyNumber fuzzyNumber : ruleBase.get(i).getAntecedents()) {
System.out.print(fuzzyNumber.toString() + "\t");
}
System.out.println(ruleBase.get(i).getConsequence().toString());
}
System.out.println("----------------------------");
}
public static void printRulesInt(RuleBase ruleBase) {
for (int i = 0; i < ruleBase.size(); i++) {
for (FuzzyNumber fuzzyNumber : ruleBase.get(i).getAntecedents()) {
System.out.print(fuzzyNumber.toStringInt() + "\t");
}
System.out.println(ruleBase.get(i).getConsequence().toStringInt());
}
}
public static void printRulesTex(RuleBase ruleBase) {
for (int i = 0; i < ruleBase.size(); i++) {
System.out.print("C" + (i + 1) + " & ");
for (FuzzyNumber fuzzyNumber : ruleBase.get(i).getAntecedents()) {
System.out.print(fuzzyNumber.toString() + " & ");
}
System.out.println(ruleBase.get(i).getConsequence().toString() + "\\\\\\hline");
}
System.out.println("----------------------------");
}
public static void printArrays(float[][] arrays) {
//StringBuffer stringBuffer = new StringBuffer();
for (int j = 0; j < arrays[0].length; j++) {
for (int i = 0; i < arrays.length; i++) {
System.out.format("%8.2f", arrays[i][j]);
}
System.out.print("\n");
}
//System.out.println(stringBuffer.toString());
}
}