public static List<FuzzyVariable> Stretch( List<MeasurementWithResult> learningSet, DecisionMakerType1 originalDecisionMaker, VariableMFParam toStretch, BoundType boundType) { List<MeasurementWithResult> withResultsFromFs = (from measurement in learningSet select new MeasurementWithResult { InputValues = new Dictionary<string, double>(measurement.InputValues), OutputString = originalDecisionMaker.InferTerm(measurement.InputValues) }).ToList(); double multiplier = 1; int error = 0; bool canStretchMore = true; if (boundType == BoundType.Upper) { while (error == 0 && canStretchMore) { multiplier += 0.001; MamdaniFuzzySystem newFuzzySystem = UpdateParamsByMultiplier( originalDecisionMaker, multiplier, toStretch, out canStretchMore); var updatedDecisionMaker = new DecisionMakerType1(newFuzzySystem, originalDecisionMaker.RulesDefinitions); error = (from measurement in withResultsFromFs where updatedDecisionMaker.InferTerm(measurement.InputValues) != measurement.OutputString select measurement).Count(); } multiplier -= 0.001; var finalFuzzySystem = UpdateParamsByMultiplier( originalDecisionMaker, multiplier, toStretch, out canStretchMore); return finalFuzzySystem.Input; } else { while (error == 0 && canStretchMore) { multiplier -= 0.001; MamdaniFuzzySystem newFuzzySystem = UpdateParamsByMultiplier( originalDecisionMaker, multiplier, toStretch, out canStretchMore); var updatedDecisionMaker = new DecisionMakerType1(newFuzzySystem, originalDecisionMaker.RulesDefinitions); error = (from measurement in withResultsFromFs where updatedDecisionMaker.InferTerm(measurement.InputValues) != measurement.OutputString select measurement).Count(); } multiplier += 0.001; var finalFuzzySystem = UpdateParamsByMultiplier( originalDecisionMaker, multiplier, toStretch, out canStretchMore); return finalFuzzySystem.Input; } }
private static MamdaniFuzzySystem UpdateParamsByMultiplier( DecisionMakerType1 originalDecisionMaker, double multiplier, VariableMFParam paramToUpdate, out bool canStretchMore) { canStretchMore = false; // Create empty fuzzy system MamdaniFuzzySystem newFs = new MamdaniFuzzySystem(); // Create input and output variables for the system foreach (var inputVariable in originalDecisionMaker.fsWellEval.Input) { FuzzyVariable fsVariable = new FuzzyVariable(inputVariable.Name, inputVariable.Min, inputVariable.Max); foreach (var term in inputVariable.Terms) { var mf = term.MembershipFunction as NormalMembershipFunction; if (paramToUpdate == VariableMFParam.Mean) { if (mf != null && (mf.B * multiplier >= fsVariable.Min && mf.B * multiplier <= fsVariable.Max)) { fsVariable.Terms.Add( new FuzzyTerm(term.Name, new NormalMembershipFunction(mf.B * multiplier, mf.Sigma))); canStretchMore = true; } else { if (mf != null) { fsVariable.Terms.Add(new FuzzyTerm(term.Name, new NormalMembershipFunction(mf.B, mf.Sigma))); canStretchMore = false; } } } if (paramToUpdate == VariableMFParam.Deviation) { if (mf != null && (mf.Sigma * multiplier >= 0.001 && mf.Sigma * multiplier <= 10)) { fsVariable.Terms.Add( new FuzzyTerm(term.Name, new NormalMembershipFunction(mf.B, mf.Sigma * multiplier))); } else { if (mf != null) { fsVariable.Terms.Add(new FuzzyTerm(term.Name, new NormalMembershipFunction(mf.B, mf.Sigma))); } } } if (paramToUpdate == VariableMFParam.RuleWeight) { if (mf != null) { fsVariable.Terms.Add(new FuzzyTerm(term.Name, new NormalMembershipFunction(mf.B, mf.Sigma))); } } } newFs.Input.Add(fsVariable); } foreach (var outputVariable in originalDecisionMaker.fsWellEval.Output) { var newVariable = new FuzzyVariable( outputVariable.Name, outputVariable.Min, outputVariable.Max, outputVariable.Unit); newVariable.Terms.Clear(); newVariable.Terms.AddRange(outputVariable.Terms); newFs.Output.Add(newVariable); } for (int i = 0; i < originalDecisionMaker.RulesDefinitions.Items.Count; i++) { MamdaniFuzzyRule newRule = newFs.ParseRule(originalDecisionMaker.RulesDefinitions.Items[i].Definition); double oldWeight = originalDecisionMaker.fsWellEval.Rules[i].Weight; if (paramToUpdate == VariableMFParam.RuleWeight) { if (oldWeight * multiplier >= 0.001 && oldWeight * multiplier <= 1) { newRule.Weight = oldWeight * multiplier; } } else { newRule.Weight = oldWeight; } newFs.Rules.Add(newRule); } return newFs; }
private void UpdateMemberships(List<FuzzyVariable> sourceVariables, VariableMFParam parameterToUpdate, BoundType boundType) { switch (parameterToUpdate) { case VariableMFParam.Mean: case VariableMFParam.Deviation: foreach (var variable in inputVariables) { foreach (var type2term in variable.Terms) { var sourceTerm = sourceVariables.Find(v => v.Name == variable.Name).Terms.Find(t => t.Name == type2term.Name); var mf = sourceTerm.MembershipFunction as NormalMembershipFunction; if (boundType == BoundType.Lower) { type2term.LowerMembershipFunction = new NormalMembershipFunction(mf.B, mf.Sigma); } else { type2term.UpperMembershipFunction = new NormalMembershipFunction(mf.B, mf.Sigma); } } } break; case VariableMFParam.RuleWeight: // todo break; } }