fuzzy_associative_memory 1.3.1 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,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