fuzzy-logic 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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ..gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fuzzy-logic (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ coderay (1.0.8)
10
+ ffi (1.3.1)
11
+ guard (1.6.1)
12
+ listen (>= 0.6.0)
13
+ lumberjack (>= 1.0.2)
14
+ pry (>= 0.9.10)
15
+ thor (>= 0.14.6)
16
+ guard-minitest (0.5.0)
17
+ guard (>= 0.4)
18
+ listen (0.7.2)
19
+ lumberjack (1.0.2)
20
+ method_source (0.8.1)
21
+ pry (0.9.10)
22
+ coderay (~> 1.0.5)
23
+ method_source (~> 0.8)
24
+ slop (~> 3.3.1)
25
+ rb-inotify (0.8.8)
26
+ ffi (>= 0.5.0)
27
+ slop (3.3.3)
28
+ thor (0.16.0)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ fuzzy-logic!
35
+ guard-minitest
36
+ rb-inotify (~> 0.8.8)
data/Guardfile ADDED
@@ -0,0 +1,24 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'minitest' do
5
+ # with Minitest::Unit
6
+ watch(%r|^test/(.*)\/?test_(.*)\.rb|)
7
+ watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
8
+ watch(%r|^test/test_helper\.rb|) { "test" }
9
+
10
+ # with Minitest::Spec
11
+ watch(%r|^spec/(.*)_spec\.rb|)
12
+ watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
13
+ watch(%r|^spec/spec_helper\.rb|) { "spec" }
14
+
15
+ # Rails 3.2
16
+ # watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/controllers/#{m[1]}_test.rb" }
17
+ # watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
18
+ # watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
19
+
20
+ # Rails
21
+ # watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/functional/#{m[1]}_test.rb" }
22
+ # watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
23
+ # watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
24
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 addisaden
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # Fuzzy-Logic
2
+
3
+ Fuzzy logic is a mathematical concept of fuzzy logical sets.
4
+ An element of a fuzzy-set belongs to it in a range between zero and one.
5
+
6
+ read my [work](http://writedown.eu/wp-content/uploads/2013/01/fuzzy-logik_fuzzy-regeln.pdf) on this topic in german.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'fuzzy-logic'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install fuzzy-logic
21
+
22
+ ## Usage
23
+
24
+ TODO: Write usage instructions here
25
+
26
+ ## Contributing
27
+
28
+ 1. Fork it
29
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
30
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
31
+ 4. Push to the branch (`git push origin my-new-feature`)
32
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :default => [:test]
4
+
5
+ task :test do
6
+ ruby "spec/spec-helper.rb"
7
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "../lib/fuzzy-logic.rb"
4
+
5
+ temp = FuzzyLogic::Collection.new("Temperatur") { |grad|
6
+ o = false
7
+ if grad < 100 and grad > -100 then
8
+ o = true
9
+ end
10
+ o
11
+ }
12
+
13
+ temp[:cold] = FuzzyLogic::Generate.trapezoid(-101,-100,5, 13)
14
+ temp[:hot] = FuzzyLogic::Generate.trapezoid(21,30,100,101)
15
+ temp[:warm] = FuzzyLogic::Generate.triangle(20, 11)
16
+ temp[:cool] = FuzzyLogic::Generate.triangle(10,11)
17
+
18
+ (0..30).to_a.each { |x|
19
+ puts "#{ x } °C"
20
+ puts temp.get(x).inspect
21
+ puts
22
+ }
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "../lib/fuzzy-logic.rb"
4
+
5
+ tageszeit = FuzzyLogic::Collection.new("Tageszeit") { |n|
6
+ o = false
7
+ if n.is_a? Time then
8
+ o = true
9
+ end
10
+ o
11
+ }
12
+
13
+ morgens_set = FuzzyLogic::Generate.triangle(8, 7)
14
+ tageszeit[:morgen] = FuzzyLogic::Set.new(1) { |n|
15
+ morgens_set.get(n.hour + n.min/60.0)
16
+ }
17
+
18
+ mittags_set = FuzzyLogic::Generate.triangle(12, 5)
19
+ tageszeit[:mittag] = FuzzyLogic::Set.new(1) { |n|
20
+ mittags_set.get(n.hour + n.min/60.0)
21
+ }
22
+
23
+ nachmittags_set = FuzzyLogic::Generate.triangle(16, 5)
24
+ tageszeit[:nachmittag] = FuzzyLogic::Set.new(1) { |n|
25
+ nachmittags_set.get(n.hour + n.min/60.0)
26
+ }
27
+
28
+ abends_set = FuzzyLogic::Generate.triangle(20, 6)
29
+ tageszeit[:abend] = FuzzyLogic::Set.new(1) { |n|
30
+ mittags_set.get(n.hour + n.min/60.0)
31
+ }
32
+
33
+ nachts_set_A = FuzzyLogic::Generate.triangle(23.9, 4)
34
+ nachts_set_B = FuzzyLogic::Generate.trapezoid(-1,0,5,9)
35
+ tageszeit[:nacht] = FuzzyLogic::Set.new(1) { |n|
36
+ t = n.hour + n.min/60.0
37
+ [nachts_set_A.get(t), nachts_set_B.get(t)].max
38
+ }
39
+
40
+ puts "Die aktuelle Tageszeit entspricht: #{ tageszeit.get(Time.now) }"
@@ -0,0 +1,93 @@
1
+ 0 °C
2
+ {:cold=>1.0}
3
+
4
+ 1 °C
5
+ {:cold=>1.0}
6
+
7
+ 2 °C
8
+ {:cold=>1.0}
9
+
10
+ 3 °C
11
+ {:cold=>1.0}
12
+
13
+ 4 °C
14
+ {:cold=>1.0}
15
+
16
+ 5 °C
17
+ {:cold=>1.0, :cool=>0.09090909090909094}
18
+
19
+ 6 °C
20
+ {:cold=>0.875, :cool=>0.2727272727272727}
21
+
22
+ 7 °C
23
+ {:cold=>0.75, :cool=>0.4545454545454546}
24
+
25
+ 8 °C
26
+ {:cold=>0.625, :cool=>0.6363636363636364}
27
+
28
+ 9 °C
29
+ {:cold=>0.5, :cool=>0.8181818181818181}
30
+
31
+ 10 °C
32
+ {:cold=>0.375, :cool=>1.0}
33
+
34
+ 11 °C
35
+ {:cold=>0.25, :cool=>0.8181818181818181}
36
+
37
+ 12 °C
38
+ {:cold=>0.125, :cool=>0.6363636363636364}
39
+
40
+ 13 °C
41
+ {:cool=>0.4545454545454546}
42
+
43
+ 14 °C
44
+ {:cool=>0.2727272727272727}
45
+
46
+ 15 °C
47
+ {:warm=>0.09090909090909094, :cool=>0.09090909090909094}
48
+
49
+ 16 °C
50
+ {:warm=>0.2727272727272727}
51
+
52
+ 17 °C
53
+ {:warm=>0.4545454545454546}
54
+
55
+ 18 °C
56
+ {:warm=>0.6363636363636364}
57
+
58
+ 19 °C
59
+ {:warm=>0.8181818181818181}
60
+
61
+ 20 °C
62
+ {:warm=>1.0}
63
+
64
+ 21 °C
65
+ {:warm=>0.8181818181818181}
66
+
67
+ 22 °C
68
+ {:hot=>0.11111111111111116, :warm=>0.6363636363636364}
69
+
70
+ 23 °C
71
+ {:hot=>0.2222222222222222, :warm=>0.4545454545454546}
72
+
73
+ 24 °C
74
+ {:hot=>0.33333333333333337, :warm=>0.2727272727272727}
75
+
76
+ 25 °C
77
+ {:hot=>0.4444444444444444, :warm=>0.09090909090909094}
78
+
79
+ 26 °C
80
+ {:hot=>0.5555555555555556}
81
+
82
+ 27 °C
83
+ {:hot=>0.6666666666666667}
84
+
85
+ 28 °C
86
+ {:hot=>0.7777777777777778}
87
+
88
+ 29 °C
89
+ {:hot=>0.8888888888888888}
90
+
91
+ 30 °C
92
+ {:hot=>1.0}
93
+
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "./lib/fuzzy-logic.rb"
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "fuzzy-logic"
8
+ gem.version = FuzzyLogic::VERSION
9
+ gem.authors = ["Adrian E."]
10
+ gem.email = ["ae@writedown.eu"]
11
+ gem.description = %q{fuzzy-logic and fuzzy-rules are really handy for some problems.}
12
+ gem.summary = %q{brings fuzzy-logic and fuzzy-rules to ruby}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency('guard-minitest')
21
+ gem.add_development_dependency('rb-inotify', '~> 0.8.8')
22
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "../fuzzy-logic.rb"
4
+
5
+ module FuzzyLogic
6
+ class Collection
7
+ def initialize(name, &test)
8
+ @name = name
9
+ # a test for inputvariables (returns true/false)
10
+ @test = test
11
+ @sets = {}
12
+ end
13
+
14
+ def length
15
+ @sets.count
16
+ end
17
+
18
+ def []=(fuzzysetname, fuzzyset)
19
+ raise ArgumentError, "Secound argument should be a Fuzzy-Set" unless fuzzyset.is_a?Set
20
+ @sets[fuzzysetname.to_sym] = fuzzyset
21
+ end
22
+
23
+ def get(n, all=false)
24
+ raise TypeError, "Test of Fuzzy-Collection is not valid" unless [true, false].include? @test.call(n)
25
+ raise ArgumentError, "Argument is not valid" unless @test.call(n)
26
+ sets_output = {}
27
+ @sets.each { |name, fset|
28
+ x = fset.get(n)
29
+ if x != 0 or all then
30
+ sets_output[name] = x
31
+ end
32
+ }
33
+ sets_output
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,76 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "../fuzzy-logic.rb"
4
+
5
+ module FuzzyLogic
6
+ module Generate
7
+ def self.gauss
8
+ #
9
+ # Gauss would be calculated with this expression:
10
+ #
11
+ # Math.exp(
12
+ # -( (n - center)/diffusion )**2
13
+ # )
14
+ #
15
+ # Problem: On an overange feedback are big numbers instead of zero
16
+ end
17
+
18
+ def self.triangle(center, range)
19
+ range = range.abs
20
+ return Set.new(1) { |n|
21
+ o = 0.0
22
+ if n == center then
23
+ o = 1.0
24
+ elsif n.between?((center-range/2.0), (center+range/2.0)) then
25
+ o = 1.0 - [1.0, (n - center).abs.to_f/(range/2.0)].min
26
+ end
27
+ o
28
+ }
29
+ end
30
+
31
+ def self.trapezoid(supmin, cormin, cormax, supmax)
32
+ supmin, cormin, cormax, supmax = *([supmin, cormin, cormax, supmax].sort.map(&:to_f))
33
+ return Set.new(1) { |n|
34
+ o = 0.0
35
+ if n.between?(cormin,cormax) then
36
+ o = 1.0
37
+ elsif n.between?(supmin,cormin) then
38
+ o = 1 - (cormin - n)/(cormin - supmin)
39
+ elsif n.between?(cormax,supmax) then
40
+ o = 1 - (n - cormax)/(supmax - cormax)
41
+ end
42
+ o
43
+ }
44
+ end
45
+
46
+ def self.singleton(*args)
47
+ args_test_array_filled_with_arrays_length(args, "Arguments of a singleton fuzzy-set should be Arrays of length 2", 2)
48
+
49
+ args = args.sort { |a,b| a.first <=> b.first }
50
+ max = args.collect { |a| a.last } .sort.last
51
+
52
+ return Set.new(max) { |n|
53
+ o = 0.0
54
+ args.each { |a|
55
+ if n == a.first then
56
+ o = a.last.to_f
57
+ break
58
+ end
59
+ }
60
+ o
61
+ }
62
+ end
63
+
64
+ def self.list(*args)
65
+ args_test_array_filled_with_arrays_length(args, "Arguments of a list fuzzy-set should be Arrays of length 2", 2)
66
+ end
67
+
68
+ private
69
+
70
+ def self.args_test_array_filled_with_arrays_length(args, msg, len)
71
+ raise ArgumentError, msg unless args.select { |arg|
72
+ (not arg.is_a? Array) or (not arg.length == len)
73
+ }.empty?
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "../fuzzy-logic.rb"
4
+
5
+ module FuzzyLogic
6
+ class Set
7
+ attr_reader :height
8
+
9
+ def initialize(height=nil, &fuzzyproc)
10
+ if height != nil then
11
+ raise ArgumentError, "Initial Height should be numeric" unless height.is_a? Numeric
12
+ raise ArgumentError, "Initial Height should be between 0 and 1" if height < 0 or height > 1
13
+ end
14
+ @fuzzyproc = fuzzyproc
15
+ @height = height
16
+ end
17
+
18
+ def support(value, alphacut=nil)
19
+ get(value, alphacut) > 0
20
+ end
21
+
22
+ def core(value, alphacut=nil)
23
+ get(value, alphacut) == 1
24
+ end
25
+
26
+ def get(value, alphacut=nil)
27
+ raise ArgumentError, "Value of fuzzy-set should be Comparable" unless value.is_a? Comparable
28
+ out = @fuzzyproc.call(value)
29
+
30
+ raise TypeError, "Output of fuzzy-set should be Numeric" unless out.is_a? Numeric
31
+ raise TypeError, "Output of fuzzy-set is out of range. Should be between 0 and 1" if out < 0 or out > 1
32
+
33
+ @height ||= out
34
+ @height = out if out > @height
35
+
36
+ if alphacut then
37
+ raise ArgumentError, "Alphacut of fuzzy-set should be Comparable" unless alphacut.is_a? Numeric
38
+ out = 0 if alphacut > out
39
+ end
40
+
41
+ return out
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ =begin
4
+
5
+ TODO: Build a Fuzzy-Set-Generator with a list as arguments ...
6
+
7
+ temp[:warm] = fuzzy_set_generator( [28,1], [15,0] )
8
+ temp[:cold] = fuzzy_set_generator( [0, 1], [15,0] )
9
+
10
+ temp[:mid] = fuzzy_set_and(fuzzy_set_complement(temp[:warm]), fuzzy_set_complement(temp[:cold]))
11
+
12
+
13
+
14
+ Generate a better view ...
15
+
16
+ TODO: Optimize Output to something like This:
17
+
18
+ 0 3 6 9 12 15 18 21 24 27 30
19
+ ---~~~+++oooOOO warm
20
+ OOOooo+++~~~--- cold
21
+
22
+ X <= >
23
+ O - 1.-.8
24
+ o - .8-.6
25
+ + - .6-.4
26
+ ~ - .4-.2
27
+ - - .2-.0
28
+ - .0
29
+
30
+ =end
31
+
32
+ require_relative "fuzzy-logic/set.rb"
33
+ require_relative "fuzzy-logic/generate.rb"
34
+ require_relative "fuzzy-logic/collection.rb"
35
+
36
+ module FuzzyLogic
37
+ VERSION = "0.0.1"
38
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ temp = {}
4
+
5
+ temp[:warm] = Proc.new { |n|
6
+ out = 0
7
+ if n >= 28
8
+ out = 1
9
+ elsif n < 28 and n >= 15
10
+ out = 1 - (28.0-n)/(28.0-15)
11
+ end
12
+ out
13
+ }
14
+
15
+ temp[:cold] = Proc.new { |n|
16
+ out = 0
17
+ if n <= 0
18
+ out = 1
19
+ elsif n < 15 and n >= 0
20
+ out = 1 - n/15.0
21
+ end
22
+ out
23
+ }
24
+
25
+ temp[:mid] = Proc.new { |n|
26
+ [(1 - temp[:cold].call(n)),(1 - temp[:warm].call(n))].min
27
+ }
28
+
29
+ temp[:cool] = Proc.new { |n|
30
+ temp[:mid].call(n)*temp[:cold].call(n)*4
31
+ }
32
+
33
+
34
+ (0..30).to_a.each { |inp|
35
+ next if inp % 2 == 1
36
+ puts "--- Testing #{ inp } °C"
37
+
38
+ tp = nil
39
+
40
+ temp.each { |n,f|
41
+ tp ||= [n, f.call(inp)]
42
+ if f.call(inp) > tp.last then
43
+ tp = [n, f.call(inp)]
44
+ end
45
+ puts "Is the weather #{ n }?\t%.2f" % f.call(inp)
46
+ }
47
+
48
+ puts "\nOn #{inp} °C the weather is #{ tp.first }!\n\n"
49
+ }
@@ -0,0 +1,128 @@
1
+ --- Testing 0 °C
2
+ Is the weather warm? 0.00
3
+ Is the weather cold? 1.00
4
+ Is the weather mid? 0.00
5
+ Is the weather cool? 0.00
6
+
7
+ On 0 °C the weather is cold!
8
+
9
+ --- Testing 2 °C
10
+ Is the weather warm? 0.00
11
+ Is the weather cold? 0.87
12
+ Is the weather mid? 0.13
13
+ Is the weather cool? 0.46
14
+
15
+ On 2 °C the weather is cold!
16
+
17
+ --- Testing 4 °C
18
+ Is the weather warm? 0.00
19
+ Is the weather cold? 0.73
20
+ Is the weather mid? 0.27
21
+ Is the weather cool? 0.78
22
+
23
+ On 4 °C the weather is cool!
24
+
25
+ --- Testing 6 °C
26
+ Is the weather warm? 0.00
27
+ Is the weather cold? 0.60
28
+ Is the weather mid? 0.40
29
+ Is the weather cool? 0.96
30
+
31
+ On 6 °C the weather is cool!
32
+
33
+ --- Testing 8 °C
34
+ Is the weather warm? 0.00
35
+ Is the weather cold? 0.47
36
+ Is the weather mid? 0.53
37
+ Is the weather cool? 1.00
38
+
39
+ On 8 °C the weather is cool!
40
+
41
+ --- Testing 10 °C
42
+ Is the weather warm? 0.00
43
+ Is the weather cold? 0.33
44
+ Is the weather mid? 0.67
45
+ Is the weather cool? 0.89
46
+
47
+ On 10 °C the weather is cool!
48
+
49
+ --- Testing 12 °C
50
+ Is the weather warm? 0.00
51
+ Is the weather cold? 0.20
52
+ Is the weather mid? 0.80
53
+ Is the weather cool? 0.64
54
+
55
+ On 12 °C the weather is mid!
56
+
57
+ --- Testing 14 °C
58
+ Is the weather warm? 0.00
59
+ Is the weather cold? 0.07
60
+ Is the weather mid? 0.93
61
+ Is the weather cool? 0.25
62
+
63
+ On 14 °C the weather is mid!
64
+
65
+ --- Testing 16 °C
66
+ Is the weather warm? 0.08
67
+ Is the weather cold? 0.00
68
+ Is the weather mid? 0.92
69
+ Is the weather cool? 0.00
70
+
71
+ On 16 °C the weather is mid!
72
+
73
+ --- Testing 18 °C
74
+ Is the weather warm? 0.23
75
+ Is the weather cold? 0.00
76
+ Is the weather mid? 0.77
77
+ Is the weather cool? 0.00
78
+
79
+ On 18 °C the weather is mid!
80
+
81
+ --- Testing 20 °C
82
+ Is the weather warm? 0.38
83
+ Is the weather cold? 0.00
84
+ Is the weather mid? 0.62
85
+ Is the weather cool? 0.00
86
+
87
+ On 20 °C the weather is mid!
88
+
89
+ --- Testing 22 °C
90
+ Is the weather warm? 0.54
91
+ Is the weather cold? 0.00
92
+ Is the weather mid? 0.46
93
+ Is the weather cool? 0.00
94
+
95
+ On 22 °C the weather is warm!
96
+
97
+ --- Testing 24 °C
98
+ Is the weather warm? 0.69
99
+ Is the weather cold? 0.00
100
+ Is the weather mid? 0.31
101
+ Is the weather cool? 0.00
102
+
103
+ On 24 °C the weather is warm!
104
+
105
+ --- Testing 26 °C
106
+ Is the weather warm? 0.85
107
+ Is the weather cold? 0.00
108
+ Is the weather mid? 0.15
109
+ Is the weather cool? 0.00
110
+
111
+ On 26 °C the weather is warm!
112
+
113
+ --- Testing 28 °C
114
+ Is the weather warm? 1.00
115
+ Is the weather cold? 0.00
116
+ Is the weather mid? 0.00
117
+ Is the weather cool? 0.00
118
+
119
+ On 28 °C the weather is warm!
120
+
121
+ --- Testing 30 °C
122
+ Is the weather warm? 1.00
123
+ Is the weather cold? 0.00
124
+ Is the weather mid? 0.00
125
+ Is the weather cool? 0.00
126
+
127
+ On 30 °C the weather is warm!
128
+
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "spec_helper.rb"
4
+ require "minitest/autorun"
5
+
6
+ describe FuzzyLogic::Collection do
7
+ before do
8
+ @collection = FuzzyLogic::Collection.new("Collection Test") { |t|
9
+ o = true
10
+ if not t.is_a? Numeric then
11
+ o = false
12
+ elsif t < 0 or t > 100 then
13
+ o = false
14
+ end
15
+ o
16
+ }
17
+
18
+ @empty_collection = FuzzyLogic::Collection.new("Empty-Collection Test") { |t|
19
+ true
20
+ }
21
+
22
+ @wrong_test_collection = FuzzyLogic::Collection.new("Wrong-Proc-Test in Collection Test") { |n|
23
+ 42
24
+ }
25
+ end
26
+
27
+ describe "can add a fuzzyset" do
28
+ it "should work like a normal hash" do
29
+ @collection[:test] = FuzzyLogic::Generate.trapezoid(10,20,30,40)
30
+ end
31
+
32
+ it "should throw an error when get not FuzzySet" do
33
+ lambda { @collection[:no_fuzzy_set] = 13 }.must_raise ArgumentError
34
+ end
35
+ end
36
+
37
+ describe "give a hash on a value" do
38
+ before do
39
+ @collection[:test] = FuzzyLogic::Generate.trapezoid(10,20,30,40)
40
+ end
41
+
42
+ it "wont be empty on 25 (or 0 with true)" do
43
+ @collection.get(25).wont_be_empty
44
+ @collection.get(0, true).wont_be_empty
45
+ end
46
+
47
+ it "should be empty on 0" do
48
+ @collection.get(0).must_be_empty
49
+ end
50
+
51
+ it "should raise an error with wrong arguments" do
52
+ lambda { @collection.get("Hallo") }.must_raise ArgumentError
53
+ lambda { @collection.get(-1) }.must_raise ArgumentError
54
+ lambda { @collection.get(100.01) }.must_raise ArgumentError
55
+ end
56
+
57
+ it "should have a .length of one" do
58
+ @collection.length.must_equal 1
59
+ end
60
+ end
61
+
62
+ describe "an empty collection" do
63
+ it "should give an empty Hash on .get" do
64
+ @empty_collection.get(1).must_be :is_a?, Hash
65
+ @empty_collection.get(1).must_be_empty
66
+ end
67
+
68
+ it "should give a .length of zero" do
69
+ @empty_collection.length.must_equal 0
70
+ end
71
+ end
72
+
73
+ describe "a collection with a wrong test" do
74
+ it "should give a TypeError on get" do
75
+ lambda { @wrong_test_collection.get(1) }.must_raise TypeError
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "spec_helper.rb"
4
+ require "minitest/autorun"
5
+
6
+ describe FuzzyLogic::Generate do
7
+ before do
8
+ # @gauss
9
+ @triangle = FuzzyLogic::Generate.triangle(10,10)
10
+ @trapezoid = FuzzyLogic::Generate.trapezoid(10,20,30,40)
11
+ # @list
12
+ end
13
+
14
+ describe "a gauss fuzzy-set" do
15
+ # no test yet - no architecture ...
16
+ end
17
+
18
+ describe "a triangle fuzzy-set" do
19
+ it "should have a point with 1" do
20
+ @triangle.get(10).must_equal 1
21
+ end
22
+
23
+ it "should have also some valuse near one" do
24
+ @triangle.get(9.9).must_be :<, 1
25
+ @triangle.get(9.9).must_be :>, 0.8
26
+ @triangle.get(10.1).must_be :<, 1
27
+ @triangle.get(10.1).must_be :>, 0.8
28
+ end
29
+
30
+ it "should have also some valuse near zero" do
31
+ @triangle.get(5.1).must_be :>, 0
32
+ @triangle.get(5.1).must_be :<, 0.2
33
+ @triangle.get(14.9).must_be :>, 0
34
+ @triangle.get(14.9).must_be :<, 0.2
35
+ end
36
+
37
+ it "should have a zone with 0" do
38
+ [5,0,-15,15,20].each { |t|
39
+ @triangle.get(t).must_equal 0
40
+ }
41
+ end
42
+ end
43
+
44
+ describe "a trapezoid fuzzy-set" do
45
+ it "should have a zone with 1" do
46
+ [20,25,30].each { |t|
47
+ @trapezoid.get(t).must_equal 1
48
+ }
49
+ end
50
+
51
+ it "should have also some values near one" do
52
+ @trapezoid.get(19.9).must_be :<, 1
53
+ @trapezoid.get(19.9).must_be :>, 0.9
54
+ @trapezoid.get(30.1).must_be :<, 1
55
+ @trapezoid.get(30.1).must_be :>, 0.9
56
+ end
57
+
58
+ it "should have also some values near zero" do
59
+ @trapezoid.get(10.1).must_be :>, 0
60
+ @trapezoid.get(10.1).must_be :<, 0.1
61
+ @trapezoid.get(39.9).must_be :>, 0
62
+ @trapezoid.get(39.9).must_be :<, 0.1
63
+ end
64
+
65
+ it "should have a zone with 0" do
66
+ [0, 5, 10, 40, 41, 49, 50].each { |t|
67
+ @trapezoid.get(t).must_equal 0
68
+ }
69
+ end
70
+ end
71
+
72
+ describe "a list fuzzy-set" do
73
+ # no test yet - no architecture ...
74
+ end
75
+ end
@@ -0,0 +1,138 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "spec_helper.rb"
4
+ require "minitest/autorun"
5
+
6
+ describe FuzzyLogic::Set do
7
+ before do
8
+ @valid_set = FuzzyLogic::Set.new(1) { |n|
9
+ o = 0.0
10
+ o = 1.0 if n >= 30
11
+ o = 1.0 - (30.0 - n)/(30.0 - 20.0) if n < 30 and n >= 20
12
+ o
13
+ }
14
+
15
+ @invalid_set = FuzzyLogic::Set.new(1) { |n|
16
+ "i am invalid."
17
+ }
18
+
19
+ # Is christmas near?
20
+ @time_set = FuzzyLogic::Set.new(1) { |n|
21
+ t = Time.now
22
+ o = 0.0
23
+ if n.month == 12 and n.day <= 24 then
24
+ o = 1.0 if n.day >= 20
25
+ o = 1.0 - (24.0 - n.day)/(24.0 - 6.0) if n.day >= 6.0 and n.day < 20.0
26
+ end
27
+ o
28
+ }
29
+ end
30
+
31
+ describe "when get values from a valid set" do
32
+ it "should have a respond with 1" do
33
+ @valid_set.get(30.0).must_equal 1.0
34
+ @time_set.get(Time.new(2013,12,24)).must_equal 1.0
35
+ @time_set.get(Time.new(2013,12,20)).must_equal 1.0
36
+ end
37
+
38
+ it "should have a respond with 0" do
39
+ @valid_set.get(20).must_equal 0
40
+ @time_set.get(Time.new(2013,11)).must_equal 0
41
+ @time_set.get(Time.new(2013,12,6)).must_equal 0
42
+ end
43
+
44
+ it "should have a respond near 0" do
45
+ [@valid_set.get(21), @time_set.get(Time.new(2013,12,7))].each { |t|
46
+ t.must_be :!=, 0
47
+ t.must_be :<, 0.3
48
+ }
49
+ end
50
+
51
+ it "should have a respond near 1" do
52
+ [@valid_set.get(29), @time_set.get(Time.new(2013,12,19))].each { |t|
53
+ t.must_be :!=, 1
54
+ t.must_be :>, 0.7
55
+ }
56
+ end
57
+
58
+ it "should have a height of 1" do
59
+ @valid_set.height.must_equal 1
60
+ @time_set.height.must_equal 1
61
+ end
62
+ end
63
+
64
+ describe "when give wrong arguments" do
65
+ it "should raise an ArgumentError" do
66
+ lambda { @valid_set.get(Object.new) }.must_raise ArgumentError
67
+ lambda { @valid_set.get(2, Object.new) }.must_raise ArgumentError
68
+ end
69
+
70
+ it "should raise an TypeError" do
71
+ lambda { @invalid_set.get(3) }.must_raise TypeError
72
+ end
73
+ end
74
+
75
+ describe "should change height" do
76
+ before do
77
+ @temp_set = FuzzyLogic::Set.new(0) { |n|
78
+ o = 0.0
79
+ o = 1.0 if n > 10
80
+ o
81
+ }
82
+ end
83
+
84
+ it "should change the height from zero to one" do
85
+ @temp_set.height.must_equal 0
86
+ @temp_set.get(20)
87
+ @temp_set.height.must_equal 1
88
+ end
89
+ end
90
+
91
+ describe "if output/height of a set is out of range" do
92
+ it "should raise an error on invlalid output" do
93
+ lambda {
94
+ FuzzyLogic::Set.new { |n|
95
+ 5
96
+ }.get(1)
97
+ }.must_raise TypeError
98
+ end
99
+
100
+ it "should raise an ArgumentError on invalid initial height" do
101
+ lambda {
102
+ FuzzyLogic::Set.new(2) { |n|
103
+ true
104
+ }
105
+ }.must_raise ArgumentError
106
+
107
+ lambda {
108
+ FuzzyLogic::Set.new(:test) { |n|
109
+ true
110
+ }
111
+ }.must_raise ArgumentError
112
+ end
113
+ end
114
+
115
+ describe "fuzzy-set .support" do
116
+ it "should give only on values above zero a true value, else false" do
117
+ @valid_set.support(21).must_equal true
118
+ @valid_set.support(20).must_equal false
119
+ end
120
+
121
+ it "should also deal with alphacut" do
122
+ @valid_set.support(21, 0.5).must_equal false
123
+ @valid_set.support(26, 0.5).must_equal true
124
+ end
125
+ end
126
+
127
+ describe "fuzzy-set .core" do
128
+ it "should give only on values equal to 1 a true value" do
129
+ @valid_set.core(30).must_equal true
130
+ @valid_set.core(29).must_equal false
131
+ end
132
+
133
+ it "shouldnt have a problem with an optional alphacut" do
134
+ @valid_set.core(30, 0.5).must_equal true
135
+ @valid_set.core(29, 0.5).must_equal false
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "../../lib/fuzzy-logic.rb"
4
+
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "fuzzy-logic/set_spec.rb"
4
+ require_relative "fuzzy-logic/generate_spec.rb"
5
+ require_relative "fuzzy-logic/collection_spec.rb"
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fuzzy-logic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adrian E.
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: guard-minitest
16
+ requirement: &82009770 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *82009770
25
+ - !ruby/object:Gem::Dependency
26
+ name: rb-inotify
27
+ requirement: &82009510 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.8.8
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *82009510
36
+ description: fuzzy-logic and fuzzy-rules are really handy for some problems.
37
+ email:
38
+ - ae@writedown.eu
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - Gemfile.lock
46
+ - Guardfile
47
+ - LICENSE.txt
48
+ - README.md
49
+ - Rakefile
50
+ - demo/fuzzy-demo.rb
51
+ - demo/fuzzy-demo2.rb
52
+ - demo/output-fuzzy-demo.txt
53
+ - fuzzy-logic.gemspec
54
+ - lib/fuzzy-logic.rb
55
+ - lib/fuzzy-logic/collection.rb
56
+ - lib/fuzzy-logic/generate.rb
57
+ - lib/fuzzy-logic/set.rb
58
+ - prototype/fuzzy-prototype.rb
59
+ - prototype/output-fuzzy-prototype.txt
60
+ - spec/fuzzy-logic/collection_spec.rb
61
+ - spec/fuzzy-logic/generate_spec.rb
62
+ - spec/fuzzy-logic/set_spec.rb
63
+ - spec/fuzzy-logic/spec_helper.rb
64
+ - spec/spec-helper.rb
65
+ homepage: ''
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.11
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: brings fuzzy-logic and fuzzy-rules to ruby
89
+ test_files:
90
+ - spec/fuzzy-logic/collection_spec.rb
91
+ - spec/fuzzy-logic/generate_spec.rb
92
+ - spec/fuzzy-logic/set_spec.rb
93
+ - spec/fuzzy-logic/spec_helper.rb
94
+ - spec/spec-helper.rb
95
+ has_rdoc: