fuzzy_associative_memory 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ tmp
2
+ .ruby-version
3
+ .rspec
@@ -1,5 +1,8 @@
1
1
  # Changelog for fuzzy-associative-memory
2
2
 
3
+ ## 1.3.2, 12 September 2013
4
+ * Correct a regression in Rule
5
+
3
6
  ## 1.3.1, 2 September 2013
4
7
  * Massive performance and efficiency effort. This version of the Gem clocks in at 3.5x the speed of my 1.1 series in synthetic benchmarks. If you use the FAM in a tight loop, this will help a lot.
5
8
 
@@ -0,0 +1,24 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec, :all_on_start => true, :all_after_pass => true do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+
17
+ # Capybara features specs
18
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
19
+
20
+ # Turnip features and steps
21
+ watch(%r{^spec/acceptance/(.+)\.feature$})
22
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
23
+ end
24
+
data/Rakefile CHANGED
@@ -1,8 +1,26 @@
1
- require 'rake/testtask'
1
+ # require 'rake/testtask'
2
2
 
3
- task :default => [:test]
3
+ # task :default => [:test]
4
4
 
5
- desc "Run the test suite once"
6
- task :test do
7
- ruby "test/all_suite.rb"
5
+ # desc "Run the test suite once"
6
+ # task :test do
7
+ # ruby "test/all_suite.rb"
8
+ # end
9
+
10
+ require 'rspec/core/rake_task'
11
+
12
+ desc 'Default: run specs.'
13
+ task :default=>:spec
14
+
15
+ desc "Run specs"
16
+ RSpec::Core::RakeTask.new do |t|
17
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
18
+ # Put spec opts in a file named .rspec in root
19
+ end
20
+
21
+ desc "Generate code coverage"
22
+ RSpec::Core::RakeTask.new(:coverage) do |t|
23
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
24
+ t.rcov = true
25
+ t.rcov_opts = ['--exclude', 'spec']
8
26
  end
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'fuzzy_associative_memory'
3
+ s.version = '1.3.2'
4
+ s.date = '2013-09-12'
5
+ s.summary = "A fuzzy logic 'Fuzzy Associative Memory' (FAM) for fuzzy control systems, decision-making, artificial intelligence / AI, game agents & bots, etc."
6
+ s.description = <<-EOF
7
+ A Fuzzy Associative Memory (FAM for short) is a Fuzzy Logic tool for decision making. Fuzzy logic FAMs have a wide range of practical applications: Control systems, such as governing a fan to keep a room at the "just right" temperature; Game AI, such as imbuing bots with human-like decision-making behavior; Prediction systems, linking causes with effects. A FAM uses Fuzzy Sets to establish a set of rules that are linguistic in nature. The linguistic rules, and the fuzzy sets they contain, are defined by a human "expert" (presumably, you). The rules therefore codify intelligence and map this knowledge from the human domain to the digital.
8
+ EOF
9
+ s.authors = ["Chris Powell"]
10
+ s.email = 'cpowell@prylis.com'
11
+ s.files = `git ls-files`.split($/)
12
+ s.homepage = 'http://github.com/cpowell/fuzzy-associative-memory'
13
+ s.license = 'LGPL'
14
+ s.rdoc_options = ["--main", "README.md"]
15
+ s.add_development_dependency 'rspec'
16
+ s.add_development_dependency "rake"
17
+ end
@@ -80,7 +80,7 @@ class FuzzyAssociativeMemory::LinguisticVariable
80
80
  )
81
81
 
82
82
  if opts[:logarithmic_x]
83
- commands += "set xr [[#{[min, 1].max}:#{max}]\nset logscale x\n"
83
+ commands += "set xr [#{[min, 1].max}:#{max}]\nset logscale x\n"
84
84
  else
85
85
  commands += "set xr [#{min}:#{max}]\n"
86
86
  end
@@ -37,6 +37,7 @@ class FuzzyAssociativeMemory::Rule
37
37
  @antecedents = antecedent_array
38
38
  @consequent = consequent
39
39
  @boolean = boolean
40
+ @mus = []
40
41
  end
41
42
 
42
43
  # Triggers the rule. The antecedent(s) is/are fired with the supplied inputs
@@ -52,23 +53,15 @@ class FuzzyAssociativeMemory::Rule
52
53
  raise ArgumentError, "value array must be an collection of inputs but is a #{value_array.class}" unless value_array.is_a? Array
53
54
  raise ArgumentError, "value array passed to Rule::fire() cannot be empty" if value_array.empty?
54
55
 
55
- ant_len = @antecedents.length
56
- raise ArgumentError, "value array size must equal antecedent array size" if value_array.length != ant_len
57
-
58
- for i in 0..ant_len-1
59
- v = @antecedents[i].mu(value_array[i])
60
- @max = v if @max.nil? || v > @max
61
- @min = v if @min.nil? || v < @min
56
+ for i in 0..@antecedents.size-1
57
+ @mus[i] = @antecedents[i].mu(value_array[i])
62
58
  end
63
59
 
64
60
  if @boolean==:and
65
- return @min # AND / Intersection == minimum
61
+ return @mus.min # AND / Intersection == minimum
66
62
  else
67
- return @max # OR / Union == maximum
63
+ return @mus.max # OR / Union == maximum
68
64
  end
69
-
70
- # puts "Fired rule '#{@natural_language}': µ choices are [#{@mus.join(',')}], final µ is #{mu}" if $verbosity
71
- # [@consequent, mu]
72
65
  end
73
66
 
74
67
  end
@@ -44,12 +44,10 @@ class FuzzyAssociativeMemory::Triangle < FuzzyAssociativeMemory::FuzzySet
44
44
  end
45
45
 
46
46
  def mamdani(clip_height)
47
- left = @left
48
47
  top_left = @left + (clip_height * (@center - @left))
49
48
  top_right = @right - (clip_height * (@right - @center))
50
- right = @right
51
49
 
52
- FuzzyAssociativeMemory::Trapezoid.new(left, top_left, top_right, right, clip_height)
50
+ FuzzyAssociativeMemory::Trapezoid.new(@left, top_left, top_right, @right, clip_height)
53
51
  end
54
52
 
55
53
  def to_s
@@ -0,0 +1,19 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ require 'fuzzy_associative_memory'
8
+
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+
14
+ # Run specs in random order to surface order dependencies. If you find an
15
+ # order dependency and want to debug it, you can fix the order by providing
16
+ # the seed, which is printed after each run.
17
+ # --seed 1234
18
+ config.order = 'random'
19
+ end
@@ -0,0 +1,189 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Trapezoid" do
4
+ before :all do
5
+ # per-context setup
6
+ end
7
+
8
+ before do
9
+ # per-example setup
10
+ @t = FuzzyAssociativeMemory::Trapezoid.new(7, 10, 13, 16)
11
+ end
12
+
13
+ after do
14
+ # per-example teardown
15
+ end
16
+
17
+ after :all do
18
+ # per-context teardown
19
+ end
20
+
21
+ it "has centroid where expected" do
22
+ expect(@t.centroid_x).to eq(11.5)
23
+ end
24
+
25
+ it "has DOM 0 outside left bound" do
26
+ expect(@t.mu(2)).to eq(0)
27
+ end
28
+
29
+ it "has DOM 0 outside right bound" do
30
+ expect(@t.mu(17)).to eq(0)
31
+ end
32
+
33
+ it "has DOM 1 at peak" do
34
+ expect(@t.mu(12)).to eq(1.0)
35
+ end
36
+
37
+ it "has DOM 1 at top left" do
38
+ expect(@t.mu(10)).to eq(1.0)
39
+ end
40
+
41
+ it "has DOM 1 at top right" do
42
+ expect(@t.mu(13)).to eq(1.0)
43
+ end
44
+
45
+ it "has DOM 0.5 at half right offset" do
46
+ expect(@t.mu(14.5)).to eq(0.5)
47
+ end
48
+
49
+ it "has DOM 0.5 at half left offset" do
50
+ expect(@t.mu(8.5)).to eq(0.5)
51
+ end
52
+
53
+ it "has DOM 0 at right" do
54
+ expect(@t.mu(16)).to eq(0)
55
+ end
56
+
57
+ it "has DOM 0 at left" do
58
+ expect(@t.mu(7)).to eq(0)
59
+ end
60
+
61
+ it "has correct DOM at 3/5 offset" do
62
+ @t = FuzzyAssociativeMemory::Triangle.new(0, 5, 10)
63
+ expect(@t.mu(3.0)).to eq(0.6)
64
+ end
65
+
66
+ it "has correct DOM at 7/10 offset" do
67
+ @t = FuzzyAssociativeMemory::Triangle.new(0, 5, 10)
68
+ expect(@t.mu(7.0)).to eq(0.6)
69
+ end
70
+
71
+ context "Centroid calculation" do
72
+ it "has a proper centroid 1" do
73
+ @t=FuzzyAssociativeMemory::Trapezoid.new(0, 20, 50, 50)
74
+ expect(@t.centroid_x).to be_within(0.0005).of(29.583)
75
+ end
76
+
77
+ it "has a proper centroid 2" do
78
+ @t=FuzzyAssociativeMemory::Trapezoid.new(0, 10, 20, 30)
79
+ expect(@t.centroid_x).to eq(15)
80
+ end
81
+
82
+ it "has a proper centroid 3" do
83
+ @t=FuzzyAssociativeMemory::Trapezoid.new(50, 80, 100, 100)
84
+ expect(@t.centroid_x).to be_within(0.0005).of(81.4283)
85
+ end
86
+ end
87
+
88
+ it "has the correct DOM when fully positive" do
89
+ @t = FuzzyAssociativeMemory::Trapezoid.new(20, 30, 40, 50)
90
+ expect(@t.mu(41)).to eq(0.9)
91
+ end
92
+
93
+ context "Larsen implication" do
94
+ before do
95
+ @scaled = @t.larsen(0.15)
96
+ end
97
+
98
+ it "stays a trapezoid" do
99
+ expect(@scaled).to be_a(FuzzyAssociativeMemory::Trapezoid)
100
+ end
101
+
102
+ it "takes the height of the larsen value" do
103
+ expect(@scaled.height).to eq(0.15)
104
+ end
105
+
106
+ it "keeps same corner points" do
107
+ expect(@scaled.left).to eq(7)
108
+ expect(@scaled.top_left).to eq(10)
109
+ expect(@scaled.top_right).to eq(13)
110
+ expect(@scaled.right).to eq(16)
111
+ end
112
+ end
113
+
114
+ context "Mamdani implication" do
115
+ before do
116
+ @scaled = @t.mamdani(0.83)
117
+ end
118
+
119
+ it "stays a trapezoid" do
120
+ expect(@scaled).to be_a(FuzzyAssociativeMemory::Trapezoid)
121
+ end
122
+
123
+ it "keeps same left and right corner points" do
124
+ expect(@scaled.left).to eq(7)
125
+ expect(@scaled.right).to eq(16)
126
+ end
127
+
128
+ it "takes the height of the mamdani value" do
129
+ expect(@scaled.height).to eq(0.83)
130
+ end
131
+ end
132
+
133
+ context "Mamdani with one point at zero" do
134
+ before do
135
+ @t = FuzzyAssociativeMemory::Trapezoid.new(0, 30, 100, 110)
136
+ @scaled = @t.mamdani(0.83)
137
+ end
138
+
139
+ it "stays a trapezoid" do
140
+ expect(@scaled).to be_a(FuzzyAssociativeMemory::Trapezoid)
141
+ end
142
+
143
+ it "keeps same left and right corner points" do
144
+ expect(@scaled.left).to eq(0)
145
+ expect(@scaled.right).to eq(110)
146
+ end
147
+
148
+ it "gets the correct new top left" do
149
+ expect(@scaled.top_left).to eq(24.9)
150
+ end
151
+
152
+ it "gets the correct new top right" do
153
+ expect(@scaled.top_right).to eq(101.7)
154
+ end
155
+
156
+ it "takes the height of the mamdani value" do
157
+ expect(@scaled.height).to eq(0.83)
158
+ end
159
+ end
160
+
161
+ context "Mamdani with all points positive" do
162
+ before do
163
+ @t = FuzzyAssociativeMemory::Trapezoid.new(50, 80, 150, 160)
164
+ @scaled = @t.mamdani(0.83)
165
+ end
166
+
167
+ it "stays a trapezoid" do
168
+ expect(@scaled).to be_a(FuzzyAssociativeMemory::Trapezoid)
169
+ end
170
+
171
+ it "keeps same left and right corner points" do
172
+ expect(@scaled.left).to eq(50)
173
+ expect(@scaled.right).to eq(160)
174
+ end
175
+
176
+ it "gets the correct new top left" do
177
+ expect(@scaled.top_left).to eq(74.9)
178
+ end
179
+
180
+ it "gets the correct new top right" do
181
+ expect(@scaled.top_right).to eq(151.7)
182
+ end
183
+
184
+ it "takes the height of the mamdani value" do
185
+ expect(@scaled.height).to eq(0.83)
186
+ end
187
+ end
188
+
189
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Triangle" do
4
+ before :all do
5
+ # per-context setup
6
+ end
7
+
8
+ before do
9
+ # per-example setup
10
+ @t = FuzzyAssociativeMemory::Triangle.new(7, 10, 13)
11
+ end
12
+
13
+ after do
14
+ # per-example teardown
15
+ end
16
+
17
+ after :all do
18
+ # per-context teardown
19
+ end
20
+
21
+ it "has centroid of peak for isoceles triangle" do
22
+ expect(@t.centroid_x).to eq(10)
23
+ end
24
+
25
+ it "has DOM 0 outside left bound" do
26
+ expect(@t.mu(2)).to eq(0)
27
+ end
28
+
29
+ it "has DOM 0 outside right bound" do
30
+ expect(@t.mu(15)).to eq(0)
31
+ end
32
+
33
+ it "has DOM 1 at peak" do
34
+ expect(@t.mu(10)).to eq(1.0)
35
+ end
36
+
37
+ it "has DOM 0.5 at half right offset" do
38
+ expect(@t.mu(11.5)).to eq(0.5)
39
+ end
40
+
41
+ it "has DOM 0.5 at half left offset" do
42
+ expect(@t.mu(8.5)).to eq(0.5)
43
+ end
44
+
45
+ it "has correct DOM at 3/5 offset" do
46
+ @t = FuzzyAssociativeMemory::Triangle.new(0, 5, 10)
47
+ expect(@t.mu(3.0)).to eq(0.6)
48
+ end
49
+
50
+ it "has correct DOM at 7/10 offset" do
51
+ @t = FuzzyAssociativeMemory::Triangle.new(0, 5, 10)
52
+ expect(@t.mu(7.0)).to eq(0.6)
53
+ end
54
+
55
+ context "Larsen implication" do
56
+ before do
57
+ @scaled = @t.larsen(0.15)
58
+ end
59
+
60
+ it "takes the height of the larsen value" do
61
+ expect(@scaled.height).to eq(0.15)
62
+ end
63
+
64
+ it "keeps right, left and center" do
65
+ expect(@scaled.left).to eq(7)
66
+ expect(@scaled.right).to eq(13)
67
+ expect(@scaled.center).to eq(10)
68
+ end
69
+ end
70
+
71
+ context "Mamdani implication" do
72
+ before do
73
+ @scaled = @t.mamdani(0.83)
74
+ end
75
+
76
+ it "becomes a trapezoid" do
77
+ expect(@scaled).to be_a(FuzzyAssociativeMemory::Trapezoid)
78
+ end
79
+
80
+ it "keeps left and right" do
81
+ expect(@scaled.left).to eq(7)
82
+ expect(@scaled.right).to eq(13)
83
+ end
84
+
85
+ it "gets a proper top left" do
86
+ expect(@scaled.top_left).to eq(9.49)
87
+ end
88
+
89
+ it "gets a proper top right" do
90
+ expect(@scaled.top_right).to eq(10.51)
91
+ end
92
+
93
+ it "takes the height of the mamdani value" do
94
+ expect(@scaled.height).to eq(0.83)
95
+ end
96
+ end
97
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fuzzy_associative_memory
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,40 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-02 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-09-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ none: false
22
+ requirement: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ none: false
28
+ prerelease: false
29
+ type: :development
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ none: false
38
+ requirement: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ none: false
44
+ prerelease: false
45
+ type: :development
14
46
  description: |2
15
47
  A Fuzzy Associative Memory (FAM for short) is a Fuzzy Logic tool for decision making. Fuzzy logic FAMs have a wide range of practical applications: Control systems, such as governing a fan to keep a room at the "just right" temperature; Game AI, such as imbuing bots with human-like decision-making behavior; Prediction systems, linking causes with effects. A FAM uses Fuzzy Sets to establish a set of rules that are linguistic in nature. The linguistic rules, and the fuzzy sets they contain, are defined by a human "expert" (presumably, you). The rules therefore codify intelligence and map this knowledge from the human domain to the digital.
16
48
  email: cpowell@prylis.com
@@ -18,13 +50,12 @@ executables: []
18
50
  extensions: []
19
51
  extra_rdoc_files: []
20
52
  files:
21
- - lib/fuzzy_associative_memory.rb
22
- - lib/fuzzy_associative_memory/linguistic_variable.rb
23
- - lib/fuzzy_associative_memory/rule.rb
24
- - lib/fuzzy_associative_memory/ruleset.rb
25
- - lib/fuzzy_associative_memory/set.rb
26
- - lib/fuzzy_associative_memory/trapezoid.rb
27
- - lib/fuzzy_associative_memory/triangle.rb
53
+ - .gitignore
54
+ - CHANGELOG.md
55
+ - Guardfile
56
+ - LICENSE
57
+ - README.md
58
+ - Rakefile
28
59
  - bin/hvac_system_example.rb
29
60
  - bin/plot of distance to target.png
30
61
  - bin/plot of distance to target.svg
@@ -37,13 +68,17 @@ files:
37
68
  - bin/plot of weapon desirability.png
38
69
  - bin/plot of weapon desirability.svg
39
70
  - bin/weapon_choice_example.rb
40
- - CHANGELOG.md
41
- - LICENSE
42
- - Rakefile
43
- - README.md
44
- - test/all_suite.rb
45
- - test/trapezoid_test.rb
46
- - test/triangle_test.rb
71
+ - fuzzy_associative_memory.gemspec
72
+ - lib/fuzzy_associative_memory.rb
73
+ - lib/fuzzy_associative_memory/linguistic_variable.rb
74
+ - lib/fuzzy_associative_memory/rule.rb
75
+ - lib/fuzzy_associative_memory/ruleset.rb
76
+ - lib/fuzzy_associative_memory/set.rb
77
+ - lib/fuzzy_associative_memory/trapezoid.rb
78
+ - lib/fuzzy_associative_memory/triangle.rb
79
+ - spec/spec_helper.rb
80
+ - spec/trapezoid_spec.rb
81
+ - spec/triangle_spec.rb
47
82
  homepage: http://github.com/cpowell/fuzzy-associative-memory
48
83
  licenses:
49
84
  - LGPL
@@ -1,11 +0,0 @@
1
- # This is a whole test suite.
2
- #
3
- # $ ruby test/all_suite.rb
4
- # or just
5
- # $ rake test
6
-
7
- # require 'simplecov'
8
- # SimpleCov.start
9
-
10
- require "test/triangle_test"
11
- require "test/trapezoid_test"
@@ -1,96 +0,0 @@
1
- gem 'minitest'
2
- require 'minitest/autorun'
3
-
4
- $:.push File.expand_path('../../lib/', __FILE__)
5
- require 'fuzzy_associative_memory'
6
-
7
- # ruby ./test/trapezoid_test.rb
8
-
9
- class TrapezoidTest < MiniTest::Unit::TestCase
10
- def setup
11
- @t = FuzzyAssociativeMemory::Trapezoid.new(7, 10, 13, 16)
12
- end
13
-
14
- def test_dom_is_zero_outside_left_bound
15
- assert_equal(0, @t.mu(2))
16
- end
17
-
18
- def test_dom_is_zero_at_left
19
- assert_equal(0, @t.mu(7))
20
- end
21
-
22
- def test_dom_is_half_at_half_left_offset
23
- assert_equal(0.5, @t.mu(8.5))
24
- end
25
-
26
- def test_dom_is_one_at_top_left
27
- assert_equal(1.0, @t.mu(10))
28
- end
29
-
30
- def test_dom_is_one_at_top_right
31
- assert_equal(1.0, @t.mu(13))
32
- end
33
-
34
- def test_dom_is_half_at_half_right_offset
35
- assert_equal(0.5, @t.mu(14.5))
36
- end
37
-
38
- def test_dom_is_zero_at_right
39
- assert_equal(0, @t.mu(16))
40
- end
41
-
42
- def test_dom_is_zero_outside_right_bound
43
- assert_equal(0, @t.mu(17))
44
- end
45
-
46
- def test_dom_is_correct_at_three_fifths_offset
47
- t = FuzzyAssociativeMemory::Trapezoid.new(0, 5, 10, 15)
48
- assert_equal(0.6, t.mu(3.0))
49
- end
50
-
51
- def test_dom_is_correct_at_seven_tenths_offset
52
- t = FuzzyAssociativeMemory::Trapezoid.new(0, 5, 10, 15)
53
- assert_equal(0.6, t.mu(12.0))
54
- end
55
-
56
- def test_centroid_calculation_1
57
- t = FuzzyAssociativeMemory::Trapezoid.new(0, 20, 50, 50)
58
- assert_equal(29.583333333333332, t.centroid_x)
59
- end
60
-
61
- def test_centroid_calculation_2
62
- t = FuzzyAssociativeMemory::Trapezoid.new(0, 10, 20, 30)
63
- assert_equal(15.0, t.centroid_x)
64
- end
65
-
66
- def test_centroid_calculation_when_not_starting_at_zero
67
- t = FuzzyAssociativeMemory::Trapezoid.new(50, 80, 100, 100)
68
- assert_equal(81.42857142857143, t.centroid_x)
69
- end
70
-
71
- def test_dom_1
72
- t = FuzzyAssociativeMemory::Trapezoid.new(20, 30, 40, 50)
73
- assert_equal(0.9, t.mu(41))
74
- end
75
-
76
- def test_mamdani_clipping_1
77
- t = FuzzyAssociativeMemory::Trapezoid.new(0, 30, 100, 110)
78
- t2 = t.mamdani(0.83)
79
- assert_equal(0, t2.left)
80
- assert_equal(24.9, t2.top_left)
81
- assert_equal(101.7, t2.top_right)
82
- assert_equal(110, t2.right)
83
- assert_equal(0.83, t2.height)
84
- end
85
-
86
- def test_mamdani_clipping_2
87
- t = FuzzyAssociativeMemory::Trapezoid.new(50, 80, 150, 160)
88
- t2 = t.mamdani(0.83)
89
- assert_equal(50, t2.left)
90
- assert_equal(74.9, t2.top_left)
91
- assert_equal(151.7, t2.top_right)
92
- assert_equal(160, t2.right)
93
- assert_equal(0.83, t2.height)
94
- end
95
-
96
- end
@@ -1,64 +0,0 @@
1
- gem 'minitest'
2
- require 'minitest/autorun'
3
-
4
- $:.push File.expand_path('../../lib/', __FILE__)
5
- require 'fuzzy_associative_memory'
6
-
7
- # ruby ./test/triangle_test.rb
8
-
9
- class TriangleTest < MiniTest::Unit::TestCase
10
- def setup
11
- @t = FuzzyAssociativeMemory::Triangle.new(7, 10, 13)
12
- end
13
-
14
- def test_dom_is_zero_outside_left_bound
15
- assert_equal(0, @t.mu(2))
16
- end
17
-
18
- def test_dom_is_zero_outside_right_bound
19
- assert_equal(0, @t.mu(15))
20
- end
21
-
22
- def test_dom_is_one_at_peak
23
- assert_equal(1.0, @t.mu(10))
24
- end
25
-
26
- def test_dom_is_half_at_half_right_offset
27
- assert_equal(0.5, @t.mu(11.5))
28
- end
29
-
30
- def test_dom_is_half_at_half_left_offset
31
- assert_equal(0.5, @t.mu(8.5))
32
- end
33
-
34
- def test_dom_is_correct_at_three_fifths_offset
35
- t = FuzzyAssociativeMemory::Triangle.new(0, 5, 10)
36
- assert_equal(0.6, t.mu(3.0))
37
- end
38
-
39
- def test_dom_is_correct_at_seven_tenths_offset
40
- t = FuzzyAssociativeMemory::Triangle.new(0, 5, 10)
41
- assert_equal(0.6, t.mu(7.0))
42
- end
43
-
44
- def test_centroid_calculation
45
- t = FuzzyAssociativeMemory::Triangle.new(5, 10, 15)
46
- assert_equal(10.0, t.centroid_x)
47
- end
48
-
49
- def test_larsen_scaling
50
- scaled = @t.larsen(0.15)
51
- assert_equal(0.15, scaled.height)
52
- end
53
-
54
- def test_mamdani_clipping_1
55
- t2 = @t.mamdani(0.83)
56
- assert(t2.is_a? FuzzyAssociativeMemory::Trapezoid)
57
- assert_equal(7, t2.left)
58
- assert_equal(9.49, t2.top_left)
59
- assert_equal(10.51, t2.top_right)
60
- assert_equal(13, t2.right)
61
- assert_equal(0.83, t2.height)
62
- end
63
-
64
- end