package parameterrules; import java.io.*; import java.lang.Math; import main.BetterTokenizer; import main.GeneralInput; import parameters.ParameterSet; /** Implements the rule that the ratio of two products of input parameters has to lie between lowerBound <= ratio <= upperBound. */ public class RatioBetweenRule extends ParameterRule { /** These store the lower and upper bounds that the ratio of the parameters have to be between (inclusive of edges) */ private float lowerBound, upperBound; private int [] denomNums = new int[5]; private int numDenoms = 0; RatioBetweenRule() {} public ParameterRule copy() { RatioBetweenRule pr = (RatioBetweenRule)super.copy(); pr.denomNums = new int[numDenoms]; System.arraycopy(denomNums, 0, pr.denomNums, 0, numDenoms); return pr; } public float getFuzzyScore(float [] params) { float val = 1f; for(int i = 0; i < numParams; i++) { val *= params[paramNums[i]]; } for(int i = 0; i < numDenoms; i++) { val /= params[denomNums[i]]; } if((val < lowerBound) && (val > lowerBound / 10)) return (float)((Math.log((double)(lowerBound/val)))/Math.log((double)10)); else if(val <= lowerBound / 10) return 1.0f; else if((val > upperBound) && (val < 10 * upperBound)) return (float)((Math.log((double)(val/upperBound)))/Math.log((double)10)); else if(val >= 10 * upperBound) return 1.0f; // not the most ideal fuzzy score but it'll do. else return 0f; } public boolean changeParameters(float [] params, int mode, ParameterSet set) { System.out.println("changeParameters not yet implemented for RatioBetweenRule"); return isGood(params); } protected void loadParameter(String info, BetterTokenizer tokenizer) throws Exception { if(info.equals("Param")) { System.out.println("RatioBetweenRule ignoring inappropriate parameter specification"); } else if(info.equals("Numerator")) { if(numParams == paramNums.length) { // Expand array length int [] temp = new int[paramNums.length + 5]; System.arraycopy(paramNums, 0, temp, 0, numParams); paramNums = temp; } GeneralInput.nextToken(tokenizer); paramNums[numParams] = refParams.getPosition(tokenizer.sval); // Should throw exception if param doesn't exist numParams++; } else if(info.equals("Denominator")) { if(numDenoms == denomNums.length) { // Expand array length int [] temp = new int[denomNums.length + 5]; System.arraycopy(denomNums, 0, temp, 0, numDenoms); denomNums = temp; } GeneralInput.nextToken(tokenizer); denomNums[numDenoms] = refParams.getPosition(tokenizer.sval); // Should throw exception if param doesn't exist numDenoms++; } else if(info.equals("LowerBound")) { GeneralInput.nextToken(tokenizer); lowerBound = (float)tokenizer.nval; } else if(info.equals("UpperBound")) { GeneralInput.nextToken(tokenizer); upperBound = (float)tokenizer.nval; } else super.loadParameter(info, tokenizer); } }