home Forums # Technical Support Map getOutputValue() to the concerned membership function

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #1826
    Unknown
    Member

    Hi Juan,

    First off, I must say thank you very much for developing this amazing tool. I had zero hesitation in buying the licensed version of this application. I am running FLC models on iOS and although it took a bit of tinkering, I was able to successfully integrate all the source code into my iOS project (with Swift) and am currently using it for my Master’s thesis.

    Getting to the point, my FLC model is shown below:

    Engine: IndoorOutdoor
    InputVariable: Brightness
      enabled: true
      range: 0.000 1.000
      term: Dark PiShape 0.000 0.000 0.050 0.200
      term: Medium PiShape 0.100 0.200 0.400 0.600
      term: Bright SShape 0.450 0.750
    InputVariable: TimeOfDay
      enabled: true
      range: 0.000 1.000
      term: Daytime Triangle 0.000 0.250 0.500
      term: NightTime Triangle 0.500 0.750 1.000
    InputVariable: MagneticVariance
      enabled: true
      range: 0.000 1.000
      term: High PiShape 0.050 0.200 1.000 1.000
      term: Low PiShape 0.000 0.000 0.050 0.100
    InputVariable: DeviceMovement
      enabled: true
      range: 0.000 1.000
      term: Moving Triangle 0.000 0.250 0.500
      term: NotMoving Triangle 0.500 0.750 1.000
    OutputVariable: BrightnessIndoorOutdoor
      enabled: true
      range: 0.000 1.000
      accumulation: Maximum
      defuzzifier: Centroid 200
      default: nan
      lock-previous: false
      lock-range: false
      term: SemiOutdoor Triangle 0.250 0.500 0.750
      term: Indoor Triangle 0.000 0.250 0.500
      term: Outdoor Triangle 0.500 0.750 1.000
    OutputVariable: MagneticIndoorOutdoor
      enabled: true
      range: 0.000 1.000
      accumulation: Maximum
      defuzzifier: Centroid 200
      default: nan
      lock-previous: false
      lock-range: false
      term: SemiOutdoor Triangle 0.250 0.500 0.750
      term: Indoor Triangle 0.000 0.250 0.500
      term: Outdoor Triangle 0.500 0.750 1.000
    RuleBlock: BrightnessIndoorOutdoorRB
      enabled: true
      conjunction: Minimum
      disjunction: Maximum
      activation: Minimum
      rule: if Brightness is Dark and TimeOfDay is Daytime then BrightnessIndoorOutdoor is Indoor
      rule: if Brightness is Dark and TimeOfDay is NightTime then BrightnessIndoorOutdoor is Outdoor with 0.75
      rule: if Brightness is Dark and TimeOfDay is NightTime then BrightnessIndoorOutdoor is SemiOutdoor with 0.25
      rule: if Brightness is Medium and TimeOfDay is Daytime then BrightnessIndoorOutdoor is Indoor
      rule: if Brightness is Medium and TimeOfDay is NightTime then BrightnessIndoorOutdoor is Indoor with 0.5
      rule: if Brightness is Bright and TimeOfDay is Daytime then BrightnessIndoorOutdoor is Outdoor with 0.75
      rule: if Brightness is Bright and TimeOfDay is Daytime then BrightnessIndoorOutdoor is SemiOutdoor with 0.25
      rule: if Brightness is Bright and TimeOfDay is NightTime then BrightnessIndoorOutdoor is Outdoor with 0.25
      rule: if Brightness is Bright and TimeOfDay is NightTime then BrightnessIndoorOutdoor is SemiOutdoor with 0.75
    RuleBlock: MagneticIndoorOutdoorRB
      enabled: true
      conjunction: Minimum
      disjunction: Maximum
      activation: Minimum
      rule: if MagneticVariance is Low and DeviceMovement is Moving then MagneticIndoorOutdoor is Outdoor
      rule: if MagneticVariance is High and DeviceMovement is Moving then MagneticIndoorOutdoor is Indoor with 0.75
      rule: if MagneticVariance is High and DeviceMovement is Moving then MagneticIndoorOutdoor is SemiOutdoor with 0.25
    

    My C++ code to process incoming data is:

    if (data->input_data.movement == DEVICE_MOVEMENT_MOVING) {
        indoorOutdoorEngine->getInputVariable("DeviceMovement")->setInputValue(DEVICE_MOVEMENT_MOVING_FLC_VALUE);
      } else {
        indoorOutdoorEngine->getInputVariable("DeviceMovement")->setInputValue(DEVICE_MOVEMENT_NOT_MOVING_FLC_VALUE);
      }
      indoorOutdoorEngine->getInputVariable("Brightness")->setInputValue(data->input_data.brightness);
      if (data->input_data.daytime_or_nighttime) {
        indoorOutdoorEngine->getInputVariable("TimeOfDay")->setInputValue(DAYTIME_CATEGORY_DAYTIME_FLC_VALUE);
      } else {
        indoorOutdoorEngine->getInputVariable("TimeOfDay")->setInputValue(DAYTIME_CATEGORY_NIGHTTIME_FLC_VALUE);
      }
      indoorOutdoorEngine->getInputVariable("MagneticVariance")->setInputValue(data->input_data.magnetic_variance);
      indoorOutdoorEngine->process();
      data->output_data.results[0] = indoorOutdoorEngine->getOutputValue("BrightnessIndoorOutdoor");
      data->output_data.results_count++;
      data->output_data.results[1] = indoorOutdoorEngine->getOutputValue("MagneticIndoorOutdoor");
      data->output_data.results_count++;
    

    Currently the fuzzy logic’s output result is simply a scalar – for example 0.25 or 0.33. Because the conjunction operator is Minimum, disjunction is Maximum, I want to know how can I map this scalar value back to the concerned fuzzy membership function? For example, with my logic, if the engine output is 0.25 – how do I know if it is indoor or outdoor or semi-outdoor?

    Thanks,
    Abhishek.

    #1827

    Hi Abhishek,

    thank you for your kind words and contribution.

    First, the output of your controller is a fuzzy value. For example, \tilde{y} = 0.3/indoor+0.4/outdoor+0.2/semioutdoor. This fuzzy output is then defuzzified, which results in the scalar value y=0.33 that you mention.

    You are asking to find out whether your fuzzy output is indoor, outdoor, semioutdoor. And the answer is: it is likely to be a fuzzy value including all options. Having this in mind, I think what you may be after is what is the "truncated" output? removing all fuzziness.

    You have two options.

    (1) Fuzzification after Defuzzification: You take the output value y=2.5, and you find the Term in the OutputVariable with highest membership function for y, that is, the term with the highest \mu(y). You can do this by utilising Term* term = outputVariable->highestMembershipFunction(y);. Optionally, you can pass scalar highest to store the highest \mu(y): Term* term = outputVariable->highestMembershipFunction(y, &highest);. This will iterate over the terms in the OutputVariable and return the one with the highest \mu.

    (2) FuzzyOutput. You find the term with the highest accumulated activation degree in your outputVariable->fuzzyOutput().

     scalar highestActivation = -fl::inf; scalar highestTerm = fl::null;
    for const Term* term in OutputVariable:
       scalar accumulatedActivation = outputVariable->fuzzyOutput()->activationDegree(term);
       if (accumulatedActivation > highestActivation){
           highestActivation = accumulatedActivation;
           highestTerm = term;
       }
    

    I prefer (2) over (1) because in (1) you lose information after defuzzification.

    Methods (1) and (2) can be clearly seen in QtFuzzyLite 5. In main window, on your OutputVariable, click on in ỹ=0.000/LOW + 0.320/MEDIUM + 0.680/HIGH. This will swap to μ(y)=0.000/LOW + 0.352/MEDIUM + 0.648/HIGH. As you can see, is (2), and μ(y) is (1).

    Please, let me know if this answers your question.

    Cheers.

    #1828
    Unknown
    Member

    Hey Juan,

    Thanks a lot for the prompt answer! Yes – I was exactly looking for this. A couple of questions:

    1. I will definitely go for approach since with approach 1 you will lose information as you mention. However, my question is what are some considerations one takes when you pick a specific methods of defuzzification and accumulation? In most of my models I am simply using Centroid for defuzzification and minimum for accumulation. Can you share some insight on this?
    2. I am planning on using the accumulated activation degree as sort of a confidence rating for my outputs – any thoughts on this?

    Cheers,
    Abhishek.

    #1842

    Hi Abisheik,

    (1) I think the best configuration is depends on the problem. Experiment and choose what you find better suits the problem. If you do not have a criteria to what suits your problem, I would suggest to continue using the Centroid, the Minimum (or AlgebraicProduct) as implication, and the Maximum (or AlgebraicSum) as the Accumulation.

    (2) I think this depends on the problem too. Just remember that the output is fuzzy, and you are choosing only a part of the output to represent it. I think with this method you also lose information, as you are ignoring the membership functions of the other terms. Just be aware of this.

    Cheers.

    #1843

    Oh,

    could you please provide some information regarding what you did to incorporate fuzzylite in your Swift project? I would greatly appreciate any useful tips to achieve so.

    #1852
    Unknown
    Member

    Hey Juan,

    To help you out I’ve created a sample Swift project that includes your source code (in the project). The model used is the default one available when you open the QT FuzzyLite application i.e. Ambient –> Power.

    I’ve created a github repository at https://github.com/senabhishek/fuzzyliteAndSwift so enjoy! Once again, thank!

    Cheers,
    Abhishek.

    #1853

    Hi,

    thank you for your time providing the details of using fuzzylite in Swift.

    Could you please add all the *necessary* files regarding authorship and licensing of fuzzylite to your copy located in https://github.com/senabhishek/fuzzyliteAndSwift/tree/master/FuzzyLiteTemplate/fuzzylite? Otherwise, it is a violation of the licensing terms.

    You may find the files in https://github.com/fuzzylite/fuzzylite.

    Thanks.

    #1854
    Unknown
    Member

    Hey Juan,

    I’ve added the necessary files to the repo and also referenced this site and the github repo for FuzzyLite in the README. Let me know if that’s fine.

    Cheers,
    Abhishek.

    #1855

    Hi Abhisek,

    thank you for your prompt response.

    The files should be within the fuzzylite folder (i.e., https://github.com/senabhishek/fuzzyliteAndSwift/tree/master/FuzzyLiteTemplate/fuzzylite) as you are the author of the swift template. Other than that, it is all good :).

    thanks again for your contribution!

    Cheers.

Viewing 9 posts - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.