static public IFuzzy Complement(IFuzzy A)
    {
        // Copy A so that later changes don't modify
        IFuzzy copy = (IFuzzy)A.Clone();

        // We lose our bounds :(
        return(new DelegateFuzzy((x) =>
                                 1.0f - copy.Membership(x)
                                 , Mathf.NegativeInfinity, Mathf.Infinity));
    }
    // Lukasiewicz t-norm derived implication
    static public IFuzzy Implication(IFuzzy A, IFuzzy B)
    {
        // Take snapshots of A and B
        IFuzzy copy_A = (IFuzzy)A.Clone();
        IFuzzy copy_B = (IFuzzy)B.Clone();

        // We lose our bounds :(
        return(new DelegateFuzzy((x) =>
                                 Mathf.Min(1 - copy_A.Membership(x) + copy_B.Membership(x), 1),
                                 Mathf.NegativeInfinity, Mathf.Infinity
                                 ));
    }
示例#3
0
        public IFuzzy ApplyRule(float x)
        {
            // Get the membership of input
            float firingLevel = input.GetTerm(inputProperty).Membership(x);
            // Copy the second rule base so that changing the linguistic base won't affect this result
            IFuzzy outCopy = (IFuzzy)output.GetTerm(outputProperty).Clone();

            // Return a delegate that clamps that value
            return(new DelegateFuzzy((y) =>
                                     Mathf.Min(outCopy.Membership(y), firingLevel),
                                     outCopy.close_left, outCopy.close_right // Bounds are same as outputProperty
                                     ));
        }
    static public IFuzzy Intersection(IFuzzy A, IFuzzy B)
    {
        // Copy A and B so that later changes don't modify this result
        IFuzzy copy_A = (IFuzzy)A.Clone();
        IFuzzy copy_B = (IFuzzy)B.Clone();

        // Compute the new bounds
        float left  = Mathf.Max(A.close_left, B.close_left);
        float right = Mathf.Min(A.close_right, B.close_right);

        return(new DelegateFuzzy((x) =>
                                 Mathf.Min(copy_A.Membership(x), copy_B.Membership(x)),
                                 left, right
                                 ));
    }
    // COG
    public static float Defuzzify(IFuzzy A)
    {
        if (A.close_left == Mathf.NegativeInfinity ||
            A.close_right == Mathf.Infinity)
        {
            Debug.LogWarning("Tried to defuzzify with infinite bounds!");
        }

        // Defuzzy crisp is just the crisp
        if (A.close_left == A.close_right)
        {
            return(A.close_right);
        }

        // The ammount of points sampled for a numerical integral approximation of the value
        const int resolution = 32;

        float interval = (A.close_right - A.close_left) / resolution;

        // Use trapezoidal rule integration approximation
        float moment = 0.0f;
        float sum    = 0.0f;

        for (int i = 0; i < resolution; ++i)
        {
            // Left bound of integration
            float left = i * interval + A.close_left;
            // Right bound of integration
            float right = left + interval;

            float integral = interval * (A.Membership(left) + A.Membership(right)) * 0.5f;

            Debug.Assert(integral >= 0.0f);

            moment += (left + interval * 0.5f) * integral;
            sum    += integral;
        }

        // If this is a flat integral, then give up and give them the midpoint
        if (sum <= 0.0f)
        {
            // Debug.LogWarning("Tried to defuzzy an empty number:" + sum);
            return((A.close_right + A.close_left) * 0.5f);
        }

        return(moment / sum);
    }
示例#6
0
    // Applies a set of rules to a given output
    private void ApplyRuleSet(Rule[] rules)
    {
        IFuzzy ruleResults = Fuzzy.Zero();

        Debug.Assert(rules.Length > 0);
        LinguisticVariable output = rules[0].output;

        for (int i = 0; i < rules.Length; ++i)
        {
            Rule r = rules[i];
            // Make sure everything in this rule exists
            if (!r.IsValid())
            {
                Debug.LogWarning("Bad fuzzy rule: " + r.ToString());
                continue;
            }
            // Make sure all of the rules have the same properties, we don't want to mix up our outputs
            Debug.Assert(r.output == output, r.output + "!=" + output);

            // Input to the fuzzy membership is the input's referenced field
            float input = r.input.value;
            // Apply the rule
            IFuzzy ruleStrength = r.ApplyRule(input);
            // Combine this input with the other inputs to the rule
            ruleResults = Fuzzy.Union(ruleResults, ruleStrength);
            // TODO maybe make this so I don't have ~n! copies of rules in memory
        }

        // Defuzzify them
        float crisp = Fuzzy.Defuzzify(ruleResults);

        if (ConfidenceLerp)
        {
            FuzzyOutput confidence = ruleResults.Membership(crisp);
            output.value = Mathf.Lerp(output.value, crisp, confidence);
        }
        else
        {
            output.value = crisp;
        }
    }
示例#7
0
 public BenchmarkTest(TextWriter sw, string methodName, IFuzzy method)
 {
     this.sw = sw;
     _methodName = methodName;
     _method = method;
 }