fuzzyfic 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ec4b2dd6e2502179b84e960af4bdfd5929c97d23
4
+ data.tar.gz: 3b99b85098eaf5b2a4ae6c6f222b22ffc894a7c0
5
+ SHA512:
6
+ metadata.gz: cf5255c1018b0635b0df0eabfb053f979d20ef9dc06081e250efb045fb1009d4084c6f9ad137b6b2df234f6f273b8a412c0476abe4aef97d38d909e5105e1d40
7
+ data.tar.gz: 109b569c912f5e698dce5c81dcb94ce4669f4f71aaba5bb2d672d9f52e621cda68c478f49edb6e4d8391916660b0352190c38e06bdb376d635d32c292cdba6fb
@@ -0,0 +1,40 @@
1
+ #Fuzzyfic
2
+ Fuzzy logic with ruby
3
+
4
+ ##Example
5
+ ```ruby
6
+ # Input 1 : Service quality
7
+ service_quality = {
8
+ bad: Fuzzyfic::Gaussian.new([0,10], 0, 1.5), # => support=[0,10], center=0, width=1.5, using [exp(-((x-center)^2)/(2*width^2))]
9
+ good: Fuzzyfic::Gaussian.new([0,10], 5, 1.5),
10
+ excellent: Fuzzyfic::Gaussian.new([0,10], 10, 1.5)
11
+ }
12
+
13
+ # Input 2 : Food
14
+ food = {
15
+ execrable: Fuzzyfic::Trapezoid.new([0,3], [0,1]),
16
+ delicious: Fuzzyfic::Trapezoid.new([7,10], [9,10])
17
+ }
18
+
19
+ # Output : Tips
20
+ tips = {
21
+ low: Fuzzyfic::Triangle.new([0,10], 5), # => support=[0,10], kernel/center/peak=5
22
+ average: Fuzzyfic::Triangle.new([10,20], 15),
23
+ high: Fuzzyfic::Triangle.new([20,30], 25)
24
+ }
25
+
26
+
27
+ # Rules
28
+ rules = []
29
+ rules.push service_quality[:bad].or(food[:execrable]).then tips[:low] # => If the service_quality is bad or the food is execrable, then the tips are low
30
+ rules.push service_quality[:good].then tips[:average]
31
+ rules.push service_quality[:excellent].or(food[:delicious]).then tips[:high]
32
+
33
+
34
+ # Apply Rules, using Centroid/COG method
35
+ Fuzzyfic::Defuzzifier.cog(rules, 6.19, 8.42)# Print 19.97 => (service_quality=6.19, food=8.42) => tips=19.97
36
+ ```
37
+
38
+ <p align="center">
39
+ <img src="examples/tips.png" alt="3D result" />
40
+ </p>
@@ -0,0 +1,11 @@
1
+ require_relative 'fuzzyfic/set.rb'
2
+ require_relative 'fuzzyfic/trapezoid.rb'
3
+ require_relative 'fuzzyfic/triangle.rb'
4
+ require_relative 'fuzzyfic/condition.rb'
5
+ require_relative 'fuzzyfic/rule.rb'
6
+ require_relative 'fuzzyfic/defuzzifier.rb'
7
+ require_relative 'fuzzyfic/gaussian.rb'
8
+
9
+
10
+ module FuzzyLogic
11
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'rule'
2
+
3
+ module Fuzzyfic
4
+ class Condition
5
+
6
+ attr_accessor :left, :right, :operator
7
+
8
+ def initialize left, right=nil, operator=nil
9
+ @left = left
10
+ @right = right
11
+ @operator = operator
12
+ end
13
+
14
+ def then set
15
+ Rule.new self, set
16
+ end
17
+
18
+ def apply v_left, v_right=nil
19
+ img_left = @left.get v_left
20
+ img_right = @right.get v_right if !@right.nil?
21
+
22
+ case @operator
23
+ when nil
24
+ img_left
25
+ when :and
26
+ [img_left, img_right].min
27
+ when :or
28
+ [img_left, img_right].max
29
+ when :not
30
+ 1.0 - img_left
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,45 @@
1
+ module Fuzzyfic
2
+ class Defuzzifier
3
+
4
+ def self.cog rules, i1, i2
5
+ ## Compute intermediate results for every rules
6
+ intermediate = []
7
+ rules.each do |r|
8
+ intermediate.push r.apply(i1, i2)
9
+ end
10
+
11
+
12
+ ## COG method (centroid)
13
+
14
+ # compute support interval
15
+ mins = []
16
+ maxs = []
17
+ intermediate.each do |i|
18
+ mins.push i.first.support.min
19
+ maxs.push i.first.support.max
20
+ end
21
+
22
+ support_min = mins.min
23
+ support_max = maxs.max
24
+
25
+
26
+ # compute cog : \frac{\sum_{x \in support} x*f(x)}{\sum_{x \in support} f(x)}
27
+ num = denum = 0.0
28
+ for x in (support_min..support_max).step(0.1)
29
+
30
+ # compute f(x) : get the maximum from all conclusion rules (as a fusion)
31
+ images = []
32
+ intermediate.each do |i|
33
+ images.push i.first.get_in_crop(x, i.last)
34
+ end
35
+ fx = images.max
36
+
37
+ num += x*fx
38
+ denum += fx
39
+ end
40
+
41
+ return denum.zero? ? 0.0 : num/denum
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'set'
2
+
3
+ module Fuzzyfic
4
+ class Gaussian < Set
5
+
6
+ def initialize support, center, width
7
+ super()
8
+ @support = support
9
+ @center = center
10
+ @width = width
11
+ end
12
+
13
+ def get x
14
+ return 0.0 if !x.between?(@support.first, @support.last)
15
+ Math.exp(-((x-@center)**2)*1.0/(2*@width**2))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ module Fuzzyfic
2
+ class Rule
3
+
4
+ def initialize premise, conclusion
5
+ @premise = premise
6
+ @conclusion = conclusion
7
+ end
8
+
9
+ def apply v_left, v_right=nil
10
+ alpha = @premise.apply v_left, v_right
11
+ [@conclusion, alpha]
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'condition'
2
+ require_relative 'rule'
3
+
4
+ module Fuzzyfic
5
+ class Set
6
+
7
+ attr_accessor :support
8
+
9
+ def initialize
10
+ end
11
+
12
+ def and set
13
+ Condition.new self, set, :and
14
+ end
15
+
16
+ def or set
17
+ Condition.new self, set, :or
18
+ end
19
+
20
+
21
+ def then set
22
+ condition = Condition.new self
23
+ Rule.new condition, set
24
+ end
25
+
26
+ # Must be overriden in sub-classes
27
+ def get x
28
+ end
29
+
30
+ def get_in_crop x, alpha
31
+ [get(x), alpha].min
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'set'
2
+
3
+ module Fuzzyfic
4
+ class Trapezoid < Set
5
+
6
+ def initialize support, kernel
7
+ super()
8
+ @support = support
9
+ @kernel = kernel
10
+ end
11
+
12
+ def get x
13
+ return 0.0 if !x.between?(@support.first, @support.last)
14
+ return 1.0 if x.between?(@kernel.first, @kernel.last)
15
+
16
+ if x < @kernel.first
17
+ a = 1.0/(@kernel.first - @support.first)
18
+ b = 1.0 - a*@kernel.first
19
+ return a*x + b
20
+ elsif x > @kernel.last
21
+ a = -1.0/(@support.last - @kernel.last)
22
+ b = 1.0 - a*@kernel.last
23
+ return a*x + b
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'set'
2
+
3
+ module Fuzzyfic
4
+ class Triangle < Set
5
+
6
+ def initialize support, center
7
+ super()
8
+ @support = support
9
+ @center = center
10
+ end
11
+
12
+ def get x
13
+ return 0.0 if !x.between?(@support.first, @support.last)
14
+ return 1.0 if x == @center
15
+
16
+ if x < @center
17
+ a = 1.0/(@center - @support.first)
18
+ b = 1.0 - a*@center
19
+ return a*x + b
20
+ elsif x > @center
21
+ a = -1.0/(@support.last - @center)
22
+ b = 1.0 - a*@center
23
+ return a*x + b
24
+ end
25
+ end
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fuzzyfic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jerome Boe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-02 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Fuzzy Logic in Ruby Language
14
+ email:
15
+ - jeromeboe@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - lib/fuzzyfic.rb
22
+ - lib/fuzzyfic/condition.rb
23
+ - lib/fuzzyfic/defuzzifier.rb
24
+ - lib/fuzzyfic/gaussian.rb
25
+ - lib/fuzzyfic/rule.rb
26
+ - lib/fuzzyfic/set.rb
27
+ - lib/fuzzyfic/trapezoid.rb
28
+ - lib/fuzzyfic/triangle.rb
29
+ homepage: https://github.com/jeromeboe/fuzzyfic
30
+ licenses: []
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 2.4.5.2
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: Fuzzy Logic in Ruby Language
52
+ test_files: []