morphological_metrics 1.1.0
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.
- checksums.yaml +7 -0
- data/.autotest +30 -0
- data/.gemtest +0 -0
- data/.minitest.rb +3 -0
- data/.travis.yml +10 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +48 -0
- data/History.txt +6 -0
- data/Manifest.txt +27 -0
- data/README.rdoc +66 -0
- data/ROADMAP.txt +63 -0
- data/Rakefile +32 -0
- data/bin/mm +3 -0
- data/lib/mm/deltas.rb +35 -0
- data/lib/mm/metric.rb +191 -0
- data/lib/mm/pairs.rb +11 -0
- data/lib/mm/ratio.rb +148 -0
- data/lib/mm/scaling.rb +27 -0
- data/lib/mm/search.rb +97 -0
- data/lib/mm.rb +11 -0
- data/lib/shortcuts.yml +49 -0
- data/test/helpers.rb +22 -0
- data/test/mm/test_deltas.rb +43 -0
- data/test/mm/test_metric.rb +168 -0
- data/test/mm/test_mm.rb +6 -0
- data/test/mm/test_pairs.rb +27 -0
- data/test/mm/test_ratio.rb +132 -0
- data/test/mm/test_scaling.rb +32 -0
- data/test/mm/test_search.rb +89 -0
- metadata +142 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 38630c4a00ff6c2cbe5dedbc373d664d6b4f33b6
|
4
|
+
data.tar.gz: 5e78dfc1aacd53e528215819c0fe6d8bd30bc2b6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1d24565d2115f43919ae9ca4960225555f991cfa97edbe5bf07534fbd038f88f929283f2025e572cab51aa542765412cdc0d7bf028dad31c25d3abfc81461ae6
|
7
|
+
data.tar.gz: 0ddbb32a053f6ad71e70eea8390df5570f979b0ee197e3589874cc02980777dec04dce5e19bc171b54ef445f9e29c9ca2989f942c5315fec199a88f12a29ad98
|
data/.autotest
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require "autotest/restart"
|
4
|
+
|
5
|
+
Autotest.add_hook :initialize do |at|
|
6
|
+
at.testlib = ".minitest"
|
7
|
+
#
|
8
|
+
# at.extra_files << "../some/external/dependency.rb"
|
9
|
+
#
|
10
|
+
# at.libs << ":../some/external"
|
11
|
+
#
|
12
|
+
# at.add_exception "vendor"
|
13
|
+
#
|
14
|
+
# at.add_mapping(/dependency.rb/) do |f, _|
|
15
|
+
# at.files_matching(/test_.*rb$/)
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# %w(TestA TestB).each do |klass|
|
19
|
+
# at.extra_class_map[klass] = "test/test_misc.rb"
|
20
|
+
# end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Autotest.add_hook :run_command do |at|
|
24
|
+
# system "rake build"
|
25
|
+
# end
|
26
|
+
|
27
|
+
Autotest.add_hook :all_good do |at|
|
28
|
+
system "rake rcov_info"
|
29
|
+
end if ENV['RCOV']
|
30
|
+
|
data/.gemtest
ADDED
File without changes
|
data/.minitest.rb
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'hoe-travis'
|
4
|
+
gem 'rake'
|
5
|
+
gem 'rake-compiler'
|
6
|
+
gem 'hoe'
|
7
|
+
|
8
|
+
group :test do
|
9
|
+
gem 'minitest', '~> 5.0'
|
10
|
+
gem 'codeclimate-test-reporter', require: nil
|
11
|
+
end
|
12
|
+
|
13
|
+
group :development do
|
14
|
+
gem 'flog'
|
15
|
+
gem 'flay'
|
16
|
+
end
|
17
|
+
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
codeclimate-test-reporter (0.3.0)
|
5
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
6
|
+
docile (1.1.5)
|
7
|
+
flay (2.5.0)
|
8
|
+
ruby_parser (~> 3.0)
|
9
|
+
sexp_processor (~> 4.0)
|
10
|
+
flog (4.2.1)
|
11
|
+
ruby_parser (~> 3.1, > 3.1.0)
|
12
|
+
sexp_processor (~> 4.4)
|
13
|
+
hashr (0.0.22)
|
14
|
+
hoe (3.12.0)
|
15
|
+
rake (>= 0.8, < 11.0)
|
16
|
+
hoe-travis (1.2)
|
17
|
+
hoe (~> 3.0)
|
18
|
+
travis-lint (~> 1.2)
|
19
|
+
minitest (5.4.0)
|
20
|
+
multi_json (1.10.1)
|
21
|
+
rake (10.3.2)
|
22
|
+
rake-compiler (0.9.2)
|
23
|
+
rake
|
24
|
+
ruby_parser (3.6.1)
|
25
|
+
sexp_processor (~> 4.1)
|
26
|
+
safe_yaml (0.9.7)
|
27
|
+
sexp_processor (4.4.3)
|
28
|
+
simplecov (0.8.2)
|
29
|
+
docile (~> 1.1.0)
|
30
|
+
multi_json
|
31
|
+
simplecov-html (~> 0.8.0)
|
32
|
+
simplecov-html (0.8.0)
|
33
|
+
travis-lint (1.8.0)
|
34
|
+
hashr (~> 0.0.22)
|
35
|
+
safe_yaml (~> 0.9.0)
|
36
|
+
|
37
|
+
PLATFORMS
|
38
|
+
ruby
|
39
|
+
|
40
|
+
DEPENDENCIES
|
41
|
+
codeclimate-test-reporter
|
42
|
+
flay
|
43
|
+
flog
|
44
|
+
hoe
|
45
|
+
hoe-travis
|
46
|
+
minitest (~> 5.0)
|
47
|
+
rake
|
48
|
+
rake-compiler
|
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
.autotest
|
2
|
+
.minitest.rb
|
3
|
+
.travis.yml
|
4
|
+
Gemfile
|
5
|
+
Gemfile.lock
|
6
|
+
History.txt
|
7
|
+
Manifest.txt
|
8
|
+
README.rdoc
|
9
|
+
ROADMAP.txt
|
10
|
+
Rakefile
|
11
|
+
bin/mm
|
12
|
+
lib/mm.rb
|
13
|
+
lib/mm/deltas.rb
|
14
|
+
lib/mm/metric.rb
|
15
|
+
lib/mm/pairs.rb
|
16
|
+
lib/mm/ratio.rb
|
17
|
+
lib/mm/scaling.rb
|
18
|
+
lib/mm/search.rb
|
19
|
+
lib/shortcuts.yml
|
20
|
+
test/helpers.rb
|
21
|
+
test/mm/test_deltas.rb
|
22
|
+
test/mm/test_metric.rb
|
23
|
+
test/mm/test_mm.rb
|
24
|
+
test/mm/test_pairs.rb
|
25
|
+
test/mm/test_ratio.rb
|
26
|
+
test/mm/test_scaling.rb
|
27
|
+
test/mm/test_search.rb
|
data/README.rdoc
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
{<img src="https://codeclimate.com/github/andrewcsmith/mm.png"
|
2
|
+
/>}[https://codeclimate.com/github/andrewcsmith/mm]
|
3
|
+
|
4
|
+
{<img src="https://travis-ci.org/andrewcsmith/mm.svg?branch=master"
|
5
|
+
/>}[https://travis-ci.org/andrewcsmith/mm]
|
6
|
+
|
7
|
+
= mm
|
8
|
+
|
9
|
+
https://www.github.com/andrewcsmith/mm
|
10
|
+
|
11
|
+
== DESCRIPTION:
|
12
|
+
|
13
|
+
Implements some Morphological Metrics, described by Larry Polansky.
|
14
|
+
|
15
|
+
== FEATURES/PROBLEMS:
|
16
|
+
|
17
|
+
* Works on anything Enumerable
|
18
|
+
* Can get a number of different MMs
|
19
|
+
* Works extra fast on large NMatrix objects
|
20
|
+
|
21
|
+
== SYNOPSIS:
|
22
|
+
|
23
|
+
Code sample, LOL
|
24
|
+
|
25
|
+
== REQUIREMENTS:
|
26
|
+
|
27
|
+
* nmatrix
|
28
|
+
* ruby
|
29
|
+
|
30
|
+
== INSTALL:
|
31
|
+
|
32
|
+
* FIX (sudo gem install, anything else)
|
33
|
+
|
34
|
+
== DEVELOPERS:
|
35
|
+
|
36
|
+
After checking out the source, run:
|
37
|
+
|
38
|
+
$ rake newb
|
39
|
+
|
40
|
+
This task will install any missing dependencies, run the tests/specs,
|
41
|
+
and generate the RDoc.
|
42
|
+
|
43
|
+
== LICENSE:
|
44
|
+
|
45
|
+
(The MIT License)
|
46
|
+
|
47
|
+
Copyright (c) 2014 FIX
|
48
|
+
|
49
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
50
|
+
a copy of this software and associated documentation files (the
|
51
|
+
'Software'), to deal in the Software without restriction, including
|
52
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
53
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
54
|
+
permit persons to whom the Software is furnished to do so, subject to
|
55
|
+
the following conditions:
|
56
|
+
|
57
|
+
The above copyright notice and this permission notice shall be
|
58
|
+
included in all copies or substantial portions of the Software.
|
59
|
+
|
60
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
61
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
62
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
63
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
64
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
65
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
66
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/ROADMAP.txt
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
- Complete functions for getting combinatorial and adjacent pairs
|
2
|
+
- fix any problems with shapes, test more thoroughly
|
3
|
+
- add the ability to recurse throughout an Array tree
|
4
|
+
- Create a selection of distance functions that work with NMatrix etc
|
5
|
+
- These should be implementation-agnostic
|
6
|
+
- Ideally they should be of the symbol/method format, where the user passes a
|
7
|
+
symbol of the method to the metric
|
8
|
+
- Create a Metric class, perhaps as a subclass of Proc
|
9
|
+
- What does it mean to subclass Proc?
|
10
|
+
- Do some research.
|
11
|
+
- What about subclassing Method? What would that give us?
|
12
|
+
- Instead of a "factory" class, the creation of the metric should take place in
|
13
|
+
its initialization.
|
14
|
+
- Metric.new should take arguments similar to DistConfig, but with a
|
15
|
+
specific implementation of OLM, OCM, etc.
|
16
|
+
- This is out of a desire to tie the selection of the logic into the
|
17
|
+
distance function.
|
18
|
+
- However, there could be MM.ocm, MM.olm, etc., functions that are
|
19
|
+
"factories" that call the normal instantiation method. But it should
|
20
|
+
not be possible to create a metric without the DistConfig in instantiation.
|
21
|
+
|
22
|
+
Implementation and interface requirements:
|
23
|
+
- Objects should implement [] and #each
|
24
|
+
- Objects should implement whatever distance method is called by the Metric
|
25
|
+
|
26
|
+
Additional distance functions should (ideally) be in their own gems.
|
27
|
+
|
28
|
+
== Metric Class Methods
|
29
|
+
|
30
|
+
=== ::new(ordering, pairing, scaling, delta)
|
31
|
+
|
32
|
+
Generates a new morphological metric based on various parameters
|
33
|
+
|
34
|
+
**ordered**: can be true or false. Corresponds to ordered/unordered.
|
35
|
+
|
36
|
+
**pairing**: Similar to the delta. If it is a Proc, then the pairing function is
|
37
|
+
called on each vector (or however it is handled by the ordering). If it is a
|
38
|
+
Symbol, then we look it up in MM::PAIRING_FUNCTIONS.
|
39
|
+
|
40
|
+
**scaling**: *always* a Proc. There are prebaked scaling functions for absolute,
|
41
|
+
relative, and unscaled that are available for use. If a Symbol is passed instead
|
42
|
+
of a Proc, it looks for the Proc in the Hash MM::SCALING_FUNCTIONS
|
43
|
+
|
44
|
+
**delta functions**: If it is a Proc, then the delta function is used as d(x, y)
|
45
|
+
on each element. If it is a symbol, then the symbol is first looked up in the
|
46
|
+
MM::DELTA_FUNCTIONS hash. If it is not found, then x.symbol(y) is attempted.
|
47
|
+
Delta functions should aspire to being as general as possible; let the source
|
48
|
+
implement the method.
|
49
|
+
|
50
|
+
**order**: this is confusing terminology - first-order and second-order
|
51
|
+
difference functions.
|
52
|
+
|
53
|
+
**interval functions**: We should instead brew the int_func into the method of
|
54
|
+
finding pairs. This is where the Pairs class might come in handy; it could
|
55
|
+
generate functions (Procs, whatever) as a factory from various values, taking
|
56
|
+
into account what each value should be compared to. It's not [element, element],
|
57
|
+
but [element, comparison-element] that matters.
|
58
|
+
|
59
|
+
=== ::olm(scaling, delta)
|
60
|
+
|
61
|
+
Generates a new morphological metric calling ::new with the given ordering and
|
62
|
+
pairing
|
63
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "hoe"
|
5
|
+
|
6
|
+
# Hoe.plugin :compiler
|
7
|
+
# Hoe.plugin :gem_prelude_sucks
|
8
|
+
# Hoe.plugin :racc
|
9
|
+
# Hoe.plugin :rcov
|
10
|
+
Hoe.plugin :flay
|
11
|
+
Hoe.plugin :flog
|
12
|
+
|
13
|
+
Hoe.plugin :travis
|
14
|
+
Hoe.plugin :inline
|
15
|
+
Hoe.plugin :minitest
|
16
|
+
Hoe.plugin :package
|
17
|
+
|
18
|
+
hoe = Hoe.spec "morphological_metrics" do |h|
|
19
|
+
developer("Andrew C. Smith", "andrewchristophersmith@gmail.com")
|
20
|
+
license "MIT" # this should match the license in the README
|
21
|
+
self.readme_file = "README.rdoc"
|
22
|
+
require_rubygems_version '>= 1.4'
|
23
|
+
end
|
24
|
+
|
25
|
+
if ENV['CODECLIMATE_REPO_TOKEN']
|
26
|
+
hoe.test_prelude = <<CC
|
27
|
+
require "codeclimate-test-reporter"
|
28
|
+
CodeClimate::TestReporter.start
|
29
|
+
CC
|
30
|
+
end
|
31
|
+
|
32
|
+
# vim: syntax=ruby
|
data/bin/mm
ADDED
data/lib/mm/deltas.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module MM
|
2
|
+
module Deltas
|
3
|
+
def self.abs n
|
4
|
+
(n[0] - n[1]).abs
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.diff n
|
8
|
+
n[0] - n[1]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.mean n
|
12
|
+
n.inject(0.0, :+) / n.size
|
13
|
+
end
|
14
|
+
|
15
|
+
# Have to scale by 0.5 in order to normalize to a max distance of 1.0
|
16
|
+
def self.direction n
|
17
|
+
(n[0] <=> n[1]) * 0.5
|
18
|
+
end
|
19
|
+
|
20
|
+
# Accepts a tuple where the quotient responds to #numerator and #denominator
|
21
|
+
def self.tenney n
|
22
|
+
->(r) { Math.log2(r.numerator * r.denominator) }.call(n[0] / n[1])
|
23
|
+
end
|
24
|
+
|
25
|
+
# Accepts a tuple of anything that Math.log2 can handle
|
26
|
+
def self.log_ratio n
|
27
|
+
Math.log2((n[0] / n[1]).to_f).abs
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.ratio n
|
31
|
+
n[0] / n[1]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
data/lib/mm/metric.rb
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module MM
|
4
|
+
class Metric
|
5
|
+
# Constructor for the Metric object.
|
6
|
+
#
|
7
|
+
# ordered - [Boolean]
|
8
|
+
# Controls whether metric is ordered
|
9
|
+
# pair - [Symbol, #call]
|
10
|
+
# Method of +MM::Deltas+, or where +Object#call+ returns an +Array+ of
|
11
|
+
# pairs.
|
12
|
+
# scale - [Symbol, #call]
|
13
|
+
# Method of +MM::Scaling+, or where +Object#call+ returns a scaled diff
|
14
|
+
# +Array+
|
15
|
+
# intra_delta - [Symbol, #call]
|
16
|
+
# Method of +MM::Deltas+, or where +Object#call+ returns +Array+ of
|
17
|
+
# differences between pairs of elements
|
18
|
+
# inter_delta - [Symbol, #call]
|
19
|
+
# Method of +MM::Deltas+, or where +Object#call+ returns +Array+ of
|
20
|
+
# differences between the diffs of the two input morphologies
|
21
|
+
#
|
22
|
+
def initialize(ordered: true, pair: nil, scale: nil, intra_delta: nil, inter_delta: nil)
|
23
|
+
@ordered = ordered
|
24
|
+
self.pair = pair
|
25
|
+
self.scale = scale
|
26
|
+
self.intra_delta = intra_delta
|
27
|
+
self.inter_delta = inter_delta
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_accessor :ordered
|
31
|
+
|
32
|
+
# Public: Gets the distance between two vectors, according to the Metric
|
33
|
+
# object. Since +Metric+ can be duck-typed to work with +intra_delta+ and
|
34
|
+
# +inter_delta+, it should be possible to nest +Metric+ objects.
|
35
|
+
#
|
36
|
+
# v1 - The vector to call on.
|
37
|
+
# v2 - The vector to compare against.
|
38
|
+
#
|
39
|
+
# Returns a [Float] distance between the two vectors.
|
40
|
+
def call v1, v2
|
41
|
+
# "Readable" method provided for the parenthetically inclined
|
42
|
+
# inter_delta(scale(intra_delta(get_pairs(v1, v2))))
|
43
|
+
inter_delta scale intra_delta get_pairs v1, v2
|
44
|
+
end
|
45
|
+
|
46
|
+
# Public: Setter method for pair.
|
47
|
+
#
|
48
|
+
# pair - [Symbol, #call]
|
49
|
+
# Method of +MM::Deltas+, or where +Object#call+ returns an +Array+ of
|
50
|
+
# pairs.
|
51
|
+
#
|
52
|
+
# Returns a [Proc] pair.
|
53
|
+
def pair= pair
|
54
|
+
protected_use_method(MM::Pairs.new, :@pair, pair)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Public: Setter method for scale.
|
58
|
+
#
|
59
|
+
# scale - Either a Proc that can process scaling, or a Symbol to look up in
|
60
|
+
# MM::Scaling.
|
61
|
+
#
|
62
|
+
# Returns scale.
|
63
|
+
def scale= scale
|
64
|
+
protected_use_method(MM::Scaling, :@scale, scale)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Public: Setter method for intra_delta.
|
68
|
+
#
|
69
|
+
# intra_delta - Either a Proc that can process the intra_delta, or a Symbol
|
70
|
+
# to look up in MM::Deltas.
|
71
|
+
#
|
72
|
+
# Returns intra_delta.
|
73
|
+
def intra_delta= intra_delta
|
74
|
+
protected_use_method(MM::Deltas, :@intra_delta, intra_delta)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Public: Setter method for inter_delta.
|
78
|
+
#
|
79
|
+
# inter_delta - Either a Proc that can process as an inter_delta, or a
|
80
|
+
# Symbol where +MM::Deltas.respond_to? Symbol == true+
|
81
|
+
#
|
82
|
+
# Returns itself. Sets the instance variable @inter_delta.
|
83
|
+
def inter_delta= inter_delta
|
84
|
+
protected_use_method(MM::Deltas, :@inter_delta, inter_delta)
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
# Private: Calls the get_pairs Proc on each of v1 and v2. In lp's
|
90
|
+
# terminology, the get_pairs Proc should return either adjacent pairs
|
91
|
+
# of each of the two vectors (for linear metrics) or all possible pair
|
92
|
+
# combinations (for combinatorial metrics). For more, see Polansky 1992.
|
93
|
+
#
|
94
|
+
# v1 - the metric to use as a base
|
95
|
+
# v2 - the metric to compare to
|
96
|
+
#
|
97
|
+
# Returns an Array of Arrays of pairs.
|
98
|
+
def get_pairs v1, v2
|
99
|
+
[v1, v2].map {|x| @pair.call(x)}
|
100
|
+
end
|
101
|
+
|
102
|
+
# Private: Applies the delta to each pair of elements in a collection
|
103
|
+
# where each pair is [elem1, elem2]
|
104
|
+
#
|
105
|
+
# vp - vector pairs
|
106
|
+
#
|
107
|
+
# Returns the vector_deltas, which is the difference between each pair of
|
108
|
+
# elements in a given vector.
|
109
|
+
def intra_delta vp
|
110
|
+
vp.map {|x| x.map {|n| @intra_delta.call(n)}}
|
111
|
+
end
|
112
|
+
|
113
|
+
# Private: Calls the scaling Proc. It's a Method, so if you want to subclass it when
|
114
|
+
# subclassing Metric (in order to do something fast and crazy) you totally can.
|
115
|
+
#
|
116
|
+
# pairs - A sequence of pairs.
|
117
|
+
#
|
118
|
+
# Returns the output of the scaling Proc, ideally a sequence of pairs.
|
119
|
+
def scale pairs
|
120
|
+
@scale.call pairs
|
121
|
+
end
|
122
|
+
|
123
|
+
# Private: Accepts a series of vectors, either a sequence of pairs or two full
|
124
|
+
# collections, and reduces them to a single vector. Does not do any scaling.
|
125
|
+
#
|
126
|
+
# diffs - [Enumerable] Series of vectors, either a sequence of pairs or two full
|
127
|
+
# collections.
|
128
|
+
#
|
129
|
+
# Returns a single vector of the diffs between the two.
|
130
|
+
def inter_delta diffs
|
131
|
+
if @ordered
|
132
|
+
# Ordered Metrics take the mean of differences
|
133
|
+
Deltas.mean(diffs[0].zip(diffs[1]).map {|x| @inter_delta.call x})
|
134
|
+
else
|
135
|
+
# Unordered Metrics take the difference of means
|
136
|
+
Deltas.abs(diffs.map {|x| @inter_delta.call x})
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Private: Performs final averaging on the output of inter_delta. Can be overwritten
|
141
|
+
# when subclassed, in case you want to use a different method of averaging
|
142
|
+
# (sum of squares, etc.)
|
143
|
+
#
|
144
|
+
# diffs - The vector of the differences between the two vector deltas. Essentially
|
145
|
+
# the output of inter_delta. Should respond to #reduce.
|
146
|
+
#
|
147
|
+
# Returns distance [Numeric] The distance calculated by the diff
|
148
|
+
def post_scale diffs
|
149
|
+
diffs.reduce(0, :+).to_f / diffs.size
|
150
|
+
end
|
151
|
+
|
152
|
+
# Private: Assigns the Method named sym, if mod responds to it, to the
|
153
|
+
# instance variable var. Otherwise, assumes that the sym is actually a Proc
|
154
|
+
# and just tries to use it straight.
|
155
|
+
#
|
156
|
+
# mod - Object to see whether it has a method.
|
157
|
+
# var - instance variable to assign to.
|
158
|
+
# sym - Symbol to lookup in mod's exposed methods.
|
159
|
+
#
|
160
|
+
# Returns +sym+.
|
161
|
+
def protected_use_method mod, var, sym
|
162
|
+
if sym.is_a?(Symbol) && mod.respond_to?(sym)
|
163
|
+
self.instance_variable_set(var, mod.method(sym))
|
164
|
+
else
|
165
|
+
self.instance_variable_set(var, sym)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
### CONVENIENCE CREATION METHODS ###
|
170
|
+
# All of the following methods are created using the YAML definition file.
|
171
|
+
# See shortcuts.yml for the full definition.
|
172
|
+
# ::olm
|
173
|
+
# ::ocm
|
174
|
+
# ::ulm
|
175
|
+
# ::ucm
|
176
|
+
# ::old
|
177
|
+
# ::ocd
|
178
|
+
# ::uld
|
179
|
+
# ::ucd
|
180
|
+
METHOD_SHORTCUTS = YAML.load(File.read(File.join(File.dirname(__FILE__), '..', 'shortcuts.yml')))
|
181
|
+
|
182
|
+
class << self
|
183
|
+
METHOD_SHORTCUTS.each do |k, v|
|
184
|
+
define_method k do |other = {}|
|
185
|
+
new((v.merge other))
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|