fuzzyrb 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ ]�#,��^L�B0�ﳘ.q��O������:|��7r�����&�L�� �ն���Y���9������nts�#����/�=���u(X�����ԍu�a�[�$ga
data/History.txt ADDED
@@ -0,0 +1,5 @@
1
+ == 1.0.0 / 2007-11-09
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
5
+
data/Manifest.txt ADDED
@@ -0,0 +1,13 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/fuzzy.rb
6
+ lib/fuzzy_inference.rb
7
+ lib/fuzzy_rule.rb
8
+ lib/fuzzy_set.rb
9
+ lib/line.rb
10
+ lib/point.rb
11
+ test/test_fuzzy.rb
12
+ test/test_fuzzy_inference.rb
13
+ test/test_fuzzy_set.rb
data/README.txt ADDED
@@ -0,0 +1,50 @@
1
+ fuzzyrb
2
+ by Roman Kamyk
3
+ http://fuzzyrb.rubyforge.org/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Implements Fuzzy Sets in Ruby. I am very beginner at this topic, so it is very basic now. Any help will be appreciated.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * Fuzzy Sets defined as line segments
12
+ * Fuzzy Rules. Only conjunction of arguments is possible.
13
+ * No error handling.
14
+ * Deffuzification as center of gravity.
15
+ * Reasoning - apply matching rule and combine the results.
16
+
17
+ == SYNOPSIS:
18
+
19
+ Cannot be used from console. See test/ for sample usage.
20
+
21
+ == REQUIREMENTS:
22
+
23
+ * Ruby
24
+
25
+ == INSTALL:
26
+
27
+ sudo gem install fuzzyrb
28
+
29
+ == LICENSE:
30
+
31
+ (The GPL License)
32
+
33
+ Copyright (C) 2007 Roman Kamyk
34
+
35
+ This program is free software: you can redistribute it and/or modify
36
+ it under the terms of the GNU General Public License as published by
37
+ the Free Software Foundation, either version 3 of the License, or
38
+ (at your option) any later version.
39
+
40
+ This program is distributed in the hope that it will be useful,
41
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
42
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43
+ GNU General Public License for more details.
44
+
45
+ You should have received a copy of the GNU General Public License
46
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
47
+
48
+ == Author
49
+ Roman 'MrStone' Kamyk (mailto:roman.kamyk@gmail.com),
50
+ Student of Poznan University Of Technology, Computing Science Institute, Inteligent Decision Support Systems
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/fuzzy.rb'
6
+
7
+ Hoe.new('fuzzyrb', Fuzzyrb::VERSION) do |p|
8
+ p.rubyforge_name = 'fuzzyrb'
9
+ p.author = 'Roman Kamyk'
10
+ p.email = 'roman.kamyk@gmail.com'
11
+ p.summary = 'Fuzzy Sets for Ruby'
12
+ p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
13
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
14
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
15
+ end
16
+
17
+ # vim: syntax=Ruby
data/lib/fuzzy.rb ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # Created by Roman Kamyk <roman.kamyk@gmail.com on 2007-11-09.
3
+ # Copyright (C) 2007 Roman Kamyk
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require 'pp'
19
+
20
+ $:.unshift(File.dirname(__FILE__) + "/../lib/")
21
+ require 'point'
22
+ require 'line'
23
+ require 'fuzzy_set'
24
+ require 'fuzzy_rule'
25
+ require 'fuzzy_inference'
26
+
27
+ module Fuzzyrb
28
+ VERSION = "1.0.0"
29
+ end
@@ -0,0 +1,19 @@
1
+ class FuzzyInference
2
+ def initialize(rules)
3
+ @rules = rules
4
+ end
5
+
6
+ def mandani(values)
7
+ result = @rules.map { |rule|
8
+ rule.mandani(values)
9
+ }.inject { |s, r| s + r }
10
+ result.weigthCenter
11
+ end
12
+
13
+ def larsen(values)
14
+ result = @rules.map { |rule|
15
+ rule.larsen(values)
16
+ }.inject { |s, r| s + r }
17
+ result.weigthCenter
18
+ end
19
+ end
data/lib/fuzzy_rule.rb ADDED
@@ -0,0 +1,24 @@
1
+ class FuzzyRule
2
+ def initialize(arguments, result)
3
+ @arguments = arguments
4
+ @result = result
5
+ end
6
+
7
+ def minOfArguments(values)
8
+ tmp = []
9
+ for i in 0..(values.length-1)
10
+ tmp << @arguments[i][values[i]]
11
+ end
12
+ tmp.min
13
+ end
14
+
15
+ def larsen(values)
16
+ min = minOfArguments(values)
17
+ @result.scale(min)
18
+ end
19
+
20
+ def mandani(values)
21
+ min = minOfArguments(values)
22
+ @result.min(min)
23
+ end
24
+ end
data/lib/fuzzy_set.rb ADDED
@@ -0,0 +1,115 @@
1
+ EPSILON = 0.0001
2
+ SCALE = 1
3
+ class FuzzySet
4
+ def initialize(points)
5
+ @points = points.sort
6
+ end
7
+
8
+ def self.trapezoid(array)
9
+ raise Exception.new("Trapezoid must have array length 4") if array.length != 4
10
+ points = []
11
+ points << Point.new(array[0], 0)
12
+ points << Point.new(array[1], SCALE)
13
+ points << Point.new(array[2], SCALE) unless array[2] == array[1]
14
+ points << Point.new(array[3], 0)
15
+ FuzzySet.new(points)
16
+ end
17
+
18
+ def toLines
19
+ lines = []
20
+ for i in 1..@points.length-1
21
+ lines << Line.new(@points[i], @points[i-1])
22
+ end
23
+ lines
24
+ end
25
+
26
+ def intersections(other)
27
+ if other.is_a?(Line)
28
+ points = []
29
+ toLines.each { |mline|
30
+ points << mline.intersect(other)
31
+ }
32
+ points.select { |point| (self[point.x]-point.y).abs <= EPSILON }
33
+ elsif other.is_a?(FuzzySet)
34
+ myLines = toLines
35
+ points = []
36
+ other.toLines.each { |line|
37
+ myLines.each { |mline|
38
+ points << mline.intersect(line)
39
+ }
40
+ }
41
+ points.select { |point|
42
+ (self[point.x]-point.y).abs + (other[point.x]-point.y).abs <= EPSILON
43
+ }
44
+ else
45
+ raise Exception.new("Unable to count intersection")
46
+ end
47
+ end
48
+
49
+ def +(other)
50
+ points = [@points, other.points, intersections(other)].flatten.uniq.sort
51
+ res = points.reject { |point|
52
+ self[point.x]-EPSILON > point.y or other[point.x]-EPSILON > point.y
53
+ }
54
+ FuzzySet.new(res)
55
+ end
56
+
57
+ def min(value)
58
+ line = Line.new(Point.new(0, value), Point.new(1, value))
59
+ points = [@points, intersections(line)].flatten.uniq.sort
60
+ res = points.reject { |p| self[p.x] - EPSILON > value }
61
+ FuzzySet.new(res)
62
+ end
63
+
64
+ # Choose min of current and _other_ set
65
+ def &(other)
66
+ points = [@points, crosspoints(other)].flatten.uniq.sort
67
+ res = []
68
+ points.each { |point|
69
+ res << point if self[point.x]-EPSILON < point.y and self[point.x]+EPSILON > point.y and other[point.x]+EPSILON >= self[point.x]
70
+ }
71
+ FuzzySet.new(res)
72
+ end
73
+ attr_reader :points
74
+
75
+ def weigthCenter()
76
+ nominator = 0.0
77
+ denominator = 0.0
78
+ for i in 1..@points.length-1
79
+ line = Line.new(@points[i], @points[i-1])
80
+ x2 = points[i].x
81
+ x1 = points[i-1].x
82
+ nominator += line.a * x2**3/3 + line.b * x2**2/2 - line.a * x1**3/3 - line.b * x1**2/2
83
+ denominator += line.a * x2**2/2 + line.b * x2 - line.a * x1**2/2 - line.b * x1
84
+ end
85
+ nominator/denominator
86
+ end
87
+
88
+ def scale(factor)
89
+ fs = FuzzySet.new(@points.map { |p| p.clone() })
90
+ fs.scale!(factor)
91
+ end
92
+
93
+ def scale!(factor)
94
+ @points.each { |point| point.y *= factor / SCALE }
95
+ self
96
+ end
97
+
98
+ def [](value)
99
+ if value<@points[0].x
100
+ return 0
101
+ elsif value > @points.last.x
102
+ return 0
103
+ end
104
+ idx = 0
105
+ while (@points[idx].x < value)
106
+ idx += 1
107
+ end
108
+ return @points[idx].y if @points[idx].x == value
109
+ x1 = @points[idx-1].x
110
+ x2 = @points[idx].x
111
+ y1 = @points[idx-1].y
112
+ y2 = @points[idx].y
113
+ return 1.0*(y2 - y1)/(x2-x1) * (value - x1) + y1
114
+ end
115
+ end
data/lib/line.rb ADDED
@@ -0,0 +1,16 @@
1
+ class Line
2
+ def initialize(p1, p2)
3
+ @a = 1.0*(p2.y-p1.y)/(p2.x-p1.x)
4
+ @b = 1.0*p1.y - @a*p1.x
5
+ # pp [p1, p2, @a, @b]
6
+ end
7
+
8
+ def intersect(other)
9
+ x = 1.0*(b-other.b)/(other.a-a)
10
+ y = 1.0*a*x+b
11
+ # pp [self, other, x, y]
12
+ Point.new(x, y)
13
+ end
14
+
15
+ attr_accessor :a, :b
16
+ end
data/lib/point.rb ADDED
@@ -0,0 +1,14 @@
1
+ class Point
2
+ def initialize(x, y)
3
+ @x = x
4
+ @y = y
5
+ end
6
+ def <=>(other)
7
+ self.x <=> other.x
8
+ end
9
+ def initialize_copy(orig)
10
+ @x = orig.x
11
+ @y = orig.y
12
+ end
13
+ attr_accessor :x, :y
14
+ end
@@ -0,0 +1,7 @@
1
+ $:.unshift(File.dirname(__FILE__) + "/../lib/")
2
+ $:.unshift(File.dirname(__FILE__) + "/../test/")
3
+ require 'test/unit'
4
+ require 'test/unit/ui/console/testrunner'
5
+
6
+ require 'test_fuzzy_set'
7
+ require 'test_fuzzy_inference'
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/ruby
2
+ $:.unshift(File.dirname(__FILE__) + "/../lib/")
3
+ require 'test/unit'
4
+ require 'fuzzy'
5
+
6
+ class TestFuzzyInference < Test::Unit::TestCase
7
+ def setup
8
+ a11 = FuzzySet.trapezoid([4, 5, 5, 10])
9
+ a12 = FuzzySet.trapezoid([10, 19, 19, 20])
10
+ a21 = FuzzySet.trapezoid([4, 9, 9, 10])
11
+ a22 = FuzzySet.trapezoid([10, 12, 13, 20])
12
+ b1 = FuzzySet.trapezoid([20, 30, 30, 40])
13
+ b2 = FuzzySet.trapezoid([30, 45, 45, 50])
14
+ r1 = FuzzyRule.new([a11, a12], b1)
15
+ r2 = FuzzyRule.new([a21, a22], b2)
16
+ @fi = FuzzyInference.new([r1, r2])
17
+ end
18
+
19
+ def test_mandani
20
+ assert_in_delta 33.71, @fi.mandani([7, 18]), 0.005
21
+ end
22
+
23
+ def test_larsen
24
+ assert_in_delta 33.58, @fi.larsen([7, 18]), 0.005
25
+ end
26
+ end
27
+
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/ruby
2
+ require 'test/unit'
3
+ require 'fuzzy'
4
+
5
+ class TestFuzzySet < Test::Unit::TestCase
6
+ def test_trapezoid1
7
+ t = FuzzySet.trapezoid([4, 5, 5, 10])
8
+ assert_equal(0, t[4])
9
+ assert_equal(1, t[5])
10
+ assert_equal(0, t[10])
11
+ assert_equal(0.5, t[4.5])
12
+ assert_equal(0.8, t[6])
13
+ assert_equal(0.6, t[7])
14
+ end
15
+
16
+ def test_trapezoid2
17
+ t = FuzzySet.trapezoid([10, 12, 13, 20])
18
+ assert_equal(0, t[9])
19
+ assert_equal(0, t[10])
20
+ assert_equal(0.5, t[11])
21
+ assert_equal(0, t[-1000])
22
+ assert_equal(1, t[12])
23
+ assert_equal(1, t[12.5])
24
+ assert_equal(1, t[13])
25
+ assert_equal(0, t[20])
26
+ assert_equal(0, t[1000])
27
+ end
28
+ end
29
+
30
+
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: fuzzyrb
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-11-10 00:00:00 +01:00
8
+ summary: Fuzzy Sets for Ruby
9
+ require_paths:
10
+ - lib
11
+ email: roman.kamyk@gmail.com
12
+ homepage: " by Roman Kamyk"
13
+ rubyforge_project: fuzzyrb
14
+ description: "== FEATURES/PROBLEMS: * Fuzzy Sets defined as line segments * Fuzzy Rules. Only conjunction of arguments is possible. * No error handling. * Deffuzification as center of gravity. * Reasoning - apply matching rule and combine the results. == SYNOPSIS: Cannot be used from console. See test/ for sample usage. == REQUIREMENTS:"
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ - |
29
+ -----BEGIN CERTIFICATE-----
30
+ MIIDODCCAiCgAwIBAgIBADANBgkqhkiG9w0BAQUFADBCMRQwEgYDVQQDDAtyb21h
31
+ bi5rYW15azEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYD
32
+ Y29tMB4XDTA3MTExMDA1MzUzM1oXDTA4MTEwOTA1MzUzM1owQjEUMBIGA1UEAwwL
33
+ cm9tYW4ua2FteWsxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixk
34
+ ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdV1ujoU4I2
35
+ daF4KANtDPTSjLYhXC1CiiyEgGEVA6GvieQ2NpNNsSXl+6tbWXGNUWFHj50rrLTC
36
+ e1dJSGGTZa9ZjI6fkeb/Gr13s71ncCJ+hBbpvktWIWdvOvzvNo9bdzNCKX00Rlk5
37
+ hQzxhm/ZxQ2VG4ZDYc/gWOCzKYH8aKrAzzdjRsxE/QMgnVbnirCGSPQTjPVhBvcX
38
+ pH2yDvZF9NOs3D89JvA4P50WRCe8/kKPx7TG9Qkd303/FmO8yDUvJn0KgiYkm1pc
39
+ Sb+kcDZnh2+2uvkygLLDQhV5m7DfFLLkgwb/t7R4tSNFqcHoa0829rnSVBbCZACg
40
+ mrXhThP3LX8CAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
41
+ BBYEFGVgSLBvjD5kTd+1XMf58PK9llj6MA0GCSqGSIb3DQEBBQUAA4IBAQCGX43w
42
+ PspP+rmsfCKztiUwtfb4d+eqW62WaAUBT37KeW8IEm3UpAe5T1c3fFm46bxM3a2Y
43
+ wUeLqSMSquXNzb2fy+3vLAUYHc4UkR5nA5kB+F3RJwuc7LJCBGlkPsCfa91dE6j5
44
+ S80vqeRf4ITITHZbFLuVFFvQb/nPGe2LtyP4+neAktSu4r7rQ5vLbQQ/NSAliFrP
45
+ pJbWXmfjKQsDKGgs1TiISC3kfLcynhCgCcbLCek5Oc0U195z36e8x3aYEJSGFVmF
46
+ y8xfBxyZ4t0FP3lTPvGMfmSKOVOjcwT4OVpzdvRXWR8lghrQlAzNG5HdOxMzeBjb
47
+ Z2byiG0rlbybmXMS
48
+ -----END CERTIFICATE-----
49
+
50
+ post_install_message:
51
+ authors:
52
+ - Roman Kamyk
53
+ files:
54
+ - History.txt
55
+ - Manifest.txt
56
+ - README.txt
57
+ - Rakefile
58
+ - lib/fuzzy.rb
59
+ - lib/fuzzy_inference.rb
60
+ - lib/fuzzy_rule.rb
61
+ - lib/fuzzy_set.rb
62
+ - lib/line.rb
63
+ - lib/point.rb
64
+ - test/test_fuzzy.rb
65
+ - test/test_fuzzy_inference.rb
66
+ - test/test_fuzzy_set.rb
67
+ test_files:
68
+ - test/test_fuzzy.rb
69
+ - test/test_fuzzy_inference.rb
70
+ - test/test_fuzzy_set.rb
71
+ rdoc_options:
72
+ - --main
73
+ - README.txt
74
+ extra_rdoc_files:
75
+ - History.txt
76
+ - Manifest.txt
77
+ - README.txt
78
+ executables: []
79
+
80
+ extensions: []
81
+
82
+ requirements: []
83
+
84
+ dependencies:
85
+ - !ruby/object:Gem::Dependency
86
+ name: hoe
87
+ version_requirement:
88
+ version_requirements: !ruby/object:Gem::Version::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 1.3.0
93
+ version:
metadata.gz.sig ADDED
Binary file