fuzzy-logic 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: