{"id":19610473,"url":"https://github.com/valiot/flex","last_synced_at":"2025-04-27T21:31:41.740Z","repository":{"id":45421075,"uuid":"184702869","full_name":"valiot/flex","owner":"valiot","description":"FLex: Fuzzy Logic for Elixir","archived":false,"fork":false,"pushed_at":"2023-09-02T20:05:34.000Z","size":219,"stargazers_count":20,"open_issues_count":0,"forks_count":1,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-24T11:49:52.241Z","etag":null,"topics":["elixir","fuzzy-logic"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/valiot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-05-03T05:23:10.000Z","updated_at":"2024-11-17T22:08:15.000Z","dependencies_parsed_at":"2024-11-11T10:30:56.323Z","dependency_job_id":"731c177f-6dc7-4c1d-8935-b1bba45bc63a","html_url":"https://github.com/valiot/flex","commit_stats":{"total_commits":35,"total_committers":1,"mean_commits":35.0,"dds":0.0,"last_synced_commit":"d092e1b8b0f38eeaed55ae29452d0b7d7f8965e4"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valiot%2Fflex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valiot%2Fflex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valiot%2Fflex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valiot%2Fflex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/valiot","download_url":"https://codeload.github.com/valiot/flex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251212033,"owners_count":21553394,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","fuzzy-logic"],"created_at":"2024-11-11T10:29:30.311Z","updated_at":"2025-04-27T21:31:41.441Z","avatar_url":"https://github.com/valiot.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/valiot/flex/master/assets/flex-logo.png\" alt=\"FLex Logo\" width=\"512\" height=\"121\" /\u003e\n\u003c/div\u003e\n\n***\n\u003cbr\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/valiot/flex/master/assets/valiot-logo-blue.png\" alt=\"Valiot Logo\" width=\"384\" height=\"80\" /\u003e\n\u003c/div\u003e\n\u003cbr\u003e\n\n\n# FLex\n\nA toolkit for fuzzy logic, this library includes functions to make fuzzy sets, variables and rules for creating a Fuzzy Logic System (FLS).\n\nThe goal of FLex is to easily design and efficiently operate fuzzy logic controllers without relying on external libraries.\n\n## Index\n\n* [Features](#features)\n\n* [Installation](#installation)\n\n* [Usage](#usage)\n    * [Sets](#sets)\n    * [Variables](#variables)\n    * [Rules](#rules)\n    * [System](#system)\n    * [ANFIS](#anfis)\n\n* [Documentation](#documentation)\n\n* [Contributing](#contributing)\n\n* [License](#License)\n\n* [TODO](#todo)\n\n## Features\n\nThe following list is the current supported backend for each component of the FLS:\n\n- Linguistic Rules:\n  - Lambda function syntax\n  - Tuple syntax\n\n- Membership functions:\n  - Triangular\n  - Trapezoidal\n  - Saturation\n  - Shoulder\n  - Gauss\n  - Generalized Bell\n  - Sigmoid\n  - Z-shaped\n  - S-shaped\n  - Pi-shaped\n  - Linear Combination (Takagi-Sugeno, ANFIS only)\n\n- Fuzzy Inference Systems:\n  - Mamdani:\n    - Inference:\n      - Min\n\n    - Output Combination:\n      - Root-sum-square\n\n    - Defuzzification:\n      - Centroid\n\n  - Takagi-Sugeno:\n    - Inference:  \n      - Max\n      - Product\n      \n    - Defuzzification:\n      - Weighted average\n\n  - ANFIS:\n    - Inference:  \n      - Max\n      - Product\n      \n    - Defuzzification:\n      - Weighted average\n\n    - Optimization Method:\n      - Backpropagation.\n      - Hybrid (Backpropagation, LSE).\n\n\n**NOTE:** All systems are single output.\n\n## Installation\n\nThe package can be installed by adding `flex` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:flex, \"~\u003e 0.1.0\"}\n  ]\nend\n```\n\n## Usage\n***\n### Sets\n**Step 1:** Define all fuzzy sets with `Flex.Set.new/1`, the following options are require:\n  - `mf_type` - (string) Defines which type of membership function uses the set (e.g., \"triangle\").\n  - `tag` - (string) defines the linguistic name of the fuzzy set (e.g., \"too hot\"),\n  - `mf_params` - The parameters of the membership function, see Membership functions.\n\n```elixir\nt_h = Flex.Set.new(tag: \"too hot\", mf_type: \"saturation\", mf_params: [-2, 0, -4])\nj_r = Flex.Set.new(tag: \"just right\", mf_type: \"triangle\", mf_params: [-2, 0, 2])\nt_c = Flex.Set.new(tag: \"too cold\", mf_type: \"shoulder\", mf_params: [0, 2, 4])\n\ng_h = Flex.Set.new(tag: \"getting hotter\", mf_type: \"saturation\", mf_params: [-5, 0, -10])\nn_c = Flex.Set.new(tag: \"no change\", mf_type: \"triangle\", mf_params: [-5, 0, 5])\ng_c = Flex.Set.new(tag: \"getting colder\", mf_type: \"shoulder\", mf_params: [0, 5, 10])\n\nco = Flex.Set.new(tag: \"cool\", mf_type: \"saturation\", mf_params: [-50, 0, -100])\nd_n = Flex.Set.new(tag: \"do nothing\", mf_type: \"triangle\", mf_params: [-50, 0, 50])\nhe = Flex.Set.new(tag: \"heat\", mf_type: \"shoulder\", mf_params: [0, 50, 100])\n```\n### Variables\n**Step 2:** Define all fuzzy variables with `Flex.Variable.new/1`, the following options are required:\n  * `:tag` - (string) Defines the linguistic name of the fuzzy variable (e.g., \"error\"),\n  * `:fuzzy_sets` - (list) Defines which type of membership function use the set (e.g., \"triangle\").\n  * `:type` - (atom) Defines the type of variable (e.g., :antecedent or :consequent),\n  * `:range` - (range) The range in which the variable exists.\n\n```elixir\nfuzzy_sets = [t_h, j_r, t_c]\nerror = Flex.Variable.new(tag: \"error\", fuzzy_sets: fuzzy_sets, type: :antecedent, range: -4..4)\n\nfuzzy_sets = [g_h, n_c, g_c]\ndt_error = Flex.Variable.new(tag: \"dt_error\", fuzzy_sets: fuzzy_sets, type: :antecedent, range: -10..10)\n\nfuzzy_sets = [co, d_n, he]\noutput = Flex.Variable.new(tag: \"output\", fuzzy_sets: fuzzy_sets, type: :consequent, range: -100..100)\n```\n### Rules\nCurrently there are two types of syntax for defining the rules `statement`:\n  * Anonymous function syntax:\n```elixir\n  r1 = fn [at1, at2, con] -\u003e\n      (at1 ~\u003e \"too hot\" \u0026\u0026\u0026 at2 ~\u003e \"getting colder\") \u003e\u003e\u003e con ~\u003e \"cool\"\n    end\n```\n  * Tuple syntax:\n```elixir\n  r1 = {{{{\"error\", \"too hot\", \"~\u003e\"}, {\"dt_error\", \"getting colder\", \"~\u003e\"}, \"\u0026\u0026\u0026\"}, \"output\",\n      \"\u003e\u003e\u003e\"}, \"cool\", \"~\u003e\"}\n```\n**Step 3:** Define all Linguistic rules with `Flex.Rule.new/1`, the following options are required:\n  - `:statement` - Defines the rule behavior.\n  - `:antecedent` - (list) Defines the input variables.\n  - `:consequent` - Defines the output variable.\n\n```elixir\n  import Flex.Rule\n  r1 =\n    {{{{\"error\", \"too hot\", \"~\u003e\"}, {\"dt_error\", \"getting colder\", \"~\u003e\"}, \"\u0026\u0026\u0026\"}, \"output\",\n      \"\u003e\u003e\u003e\"}, \"cool\", \"~\u003e\"}\n\n  r2 =\n    {{{{\"error\", \"just right\", \"~\u003e\"}, {\"dt_error\", \"getting colder\", \"~\u003e\"}, \"\u0026\u0026\u0026\"}, \"output\",\n      \"\u003e\u003e\u003e\"}, \"heat\", \"~\u003e\"}\n\n  r3 =\n    {{{{\"error\", \"too cold\", \"~\u003e\"}, {\"dt_error\", \"getting colder\", \"~\u003e\"}, \"\u0026\u0026\u0026\"}, \"output\",\n      \"\u003e\u003e\u003e\"}, \"heat\", \"~\u003e\"}\n\n  r4 =\n    {{{{\"error\", \"too hot\", \"~\u003e\"}, {\"dt_error\", \"no change\", \"~\u003e\"}, \"\u0026\u0026\u0026\"}, \"output\", \"\u003e\u003e\u003e\"},\n      \"cool\", \"~\u003e\"}\n\n  r5 =\n    {{{{\"error\", \"just right\", \"~\u003e\"}, {\"dt_error\", \"no change\", \"~\u003e\"}, \"\u0026\u0026\u0026\"}, \"output\", \"\u003e\u003e\u003e\"},\n      \"do nothing\", \"~\u003e\"}\n\n  r6 =\n    {{{{\"error\", \"too cold\", \"~\u003e\"}, {\"dt_error\", \"no change\", \"~\u003e\"}, \"\u0026\u0026\u0026\"}, \"output\", \"\u003e\u003e\u003e\"},\n      \"heat\", \"~\u003e\"}\n\n  r7 =\n    {{{{\"error\", \"too hot\", \"~\u003e\"}, {\"dt_error\", \"getting hotter\", \"~\u003e\"}, \"\u0026\u0026\u0026\"}, \"output\",\n      \"\u003e\u003e\u003e\"}, \"cool\", \"~\u003e\"}\n\n  r8 =\n    {{{{\"error\", \"just right\", \"~\u003e\"}, {\"dt_error\", \"getting hotter\", \"~\u003e\"}, \"\u0026\u0026\u0026\"}, \"output\",\n      \"\u003e\u003e\u003e\"}, \"cool\", \"~\u003e\"}\n\n  r9 =\n    {{{{\"error\", \"too cold\", \"~\u003e\"}, {\"dt_error\", \"getting hotter\", \"~\u003e\"}, \"\u0026\u0026\u0026\"}, \"output\",\n      \"\u003e\u003e\u003e\"}, \"cool\", \"~\u003e\"}\n\n  rule1 = Flex.Rule.new(statement: r1, consequent: output.tag, antecedent: [error.tag, dt_error.tag])\n  rule2 = Flex.Rule.new(statement: r2, consequent: output.tag, antecedent: [error.tag, dt_error.tag])\n  rule3 = Flex.Rule.new(statement: r3, consequent: output.tag, antecedent: [error.tag, dt_error.tag])\n  rule4 = Flex.Rule.new(statement: r4, consequent: output.tag, antecedent: [error.tag, dt_error.tag])\n  rule5 = Flex.Rule.new(statement: r5, consequent: output.tag, antecedent: [error.tag, dt_error.tag])\n  rule6 = Flex.Rule.new(statement: r6, consequent: output.tag, antecedent: [error.tag, dt_error.tag])\n  rule7 = Flex.Rule.new(statement: r7, consequent: output.tag, antecedent: [error.tag, dt_error.tag])\n  rule8 = Flex.Rule.new(statement: r8, consequent: output.tag, antecedent: [error.tag, dt_error.tag])\n  rule9 = Flex.Rule.new(statement: r9, consequent: output.tag, antecedent: [error.tag, dt_error.tag])\n\n  rules = [rule1, rule2, rule3, rule4, rule5, rule6, rule7, rule8, rule9]\n\n```\n**Note**: You need to `import Flex.Rule` module.\n\n### System\n**Step 4:** Define FLS with `Flex.System.start_link/1` or `Flex.System.start_link/2` if you want to overwrite the GenServer options; the following options are require:\n  - `:rules` - Defines the behavior of the system based on a list of rules.\n  - `:antecedent` - (list) Defines the input variables.\n  - `:consequent` - Defines the output variable.\n  - `:engine_type` - Defines the inference engine behavior (default: Mamdini).\n\n```elixir\n  {:ok, s_pid} = Flex.System.start_link(antecedent: [error, dt_error], consequent: output, rules: rules)\n```\n\n**Step 5:** Fit the FLS with a input vector using `Flex.System.compute/2`.\n```elixir\n  result = Flex.System.compute(s_pid, [-1, -2.5])\n  #result ~= -63.4 aprox\n```\n\nIn `test/system_test.exs` there is an example of use, that is based on this [example](http://robotics.ee.uwa.edu.au/courses/faulttolerant/notes/FT5.pdf).\n\n### ANFIS\nAn adaptive network-based fuzzy inference system (ANFIS) is a kind of artificial neural network that is based on Takagi–Sugeno fuzzy inference system, this implementation use backpropagation, only Gaussian \u0026 Generalized Bell Membership functions are allowed. In `examples/anfis_demo1.exs` there is an example of use.\n\n## Documentation\nThe docs can be found at [https://hexdocs.pm/flex](https://hexdocs.pm/flex).\n\n## Contributing\n  * Fork our repository on github.\n  * Fix or add what is needed.\n  * Commit to your repository.\n  * Issue a github pull request (fill the PR template).\n\n## License\n  See [LICENSE](https://github.com/valiot/flex/blob/master/LICENSE).\n\n## TODO\n  * Add more membership functions.\n  * Add more inference methods.\n  * Add more defuzzification methods.\n  * Add helper functions.\n  * Add metaprogramming for linguistic rules.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvaliot%2Fflex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvaliot%2Fflex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvaliot%2Fflex/lists"}