maia-util
Version:
Utility math and music functions supporting various applications by Music Artificial Intelligence Algorithms, Inc.
978 lines (778 loc) • 67 kB
JavaScript
const chai = require('chai')
const expect = chai.expect
const should = chai.should()
// var should = require('chai').should(),
// mma = require('../util-math'),
var mu = require('../dist/index');
// Array operations.
append_array = mu.append_array;
append_array_of_arrays = mu.append_array_of_arrays;
array_object_index_of = mu.array_object_index_of;
array_object_index_of_array = mu.array_object_index_of_array;
array_sum = mu.array_sum;
copy_array_object = mu.copy_array_object;
cyclically_permute_array_by = mu.cyclically_permute_array_by;
factorial = mu.factorial;
binomial_coefficient = mu.binomial_coefficient;
// Array.prototype.equals
// Array.prototype.index_item_1st_occurs
// Array.prototype.index_item_1st_doesnt_occur
max_argmax = mu.max_argmax;
min_argmin = mu.min_argmin;
multiply_array_by_constant = mu.multiply_array_by_constant;
// Point-set operations.
copy_point_set = mu.copy_point_set;
count_rows = mu.count_rows;
index_point_set = mu.index_point_set;
get_unique = mu.get_unique;
lex_more = mu.lex_more;
restrict_point_set_in_nth_to_xs = mu.restrict_point_set_in_nth_to_xs;
sort_rows = mu.sort_rows;
subtract_two_arrays = mu.subtract_two_arrays;
unique_rows = mu.unique_rows;
// Stats/sampling.
choose_one = mu.choose_one;
corr = mu.corr;
get_random_arbitrary = mu.get_random_arbitrary;
get_random_int = mu.get_random_int;
get_random_int_inclusive = mu.get_random_int_inclusive;
mean = mu.mean;
median = mu.median;
std = mu.std;
entropy = mu.entropy;
skewness = mu.skewness;
median_skewness = mu.median_skewness;
excess_kurtosis = mu.excess_kurtosis;
mod = mu.mod;
sample_without_replacement = mu.sample_without_replacement;
// Interpolation.
index_1st_element_gt = mu.index_1st_element_gt;
// Projection and patterns.
lex_less_or_equal_triple = mu.lex_less_or_equal_triple;
lex_less_or_equal = mu.lex_less_or_equal;
orthogonal_projection_not_unique_equalp = mu.orthogonal_projection_not_unique_equalp;
maximal_translatable_pattern = mu.maximal_translatable_pattern;
intersection = mu.intersection;
intersection_hash = mu.intersection_hash;
siar = mu.siar;
translators = mu.translators;
cardinality_score = mu.cardinality_score;
// String operations.
locations = mu.locations;
my_last_string = mu.my_last_string;
string_separated_string2array = mu.string_separated_string2array;
// Utility.
append_ontimes_to_time_signatures = mu.append_ontimes_to_time_signatures;
bar_and_beat_number_of_ontime = mu.bar_and_beat_number_of_ontime;
clef_sign_and_line2clef_name = mu.clef_sign_and_line2clef_name;
convert_1st_bar2anacrusis_val = mu.convert_1st_bar2anacrusis_val;
default_page_and_system_breaks = mu.default_page_and_system_breaks;
group_grace_by_contiguous_id = mu.group_grace_by_contiguous_id;
guess_morphetic = mu.guess_morphetic;
guess_morphetic_in_C_major = mu.guess_morphetic_in_C_major;
midi_note_morphetic_pair2pitch_and_octave = mu.midi_note_morphetic_pair2pitch_and_octave;
MNN2pitch_simple = mu.MNN2pitch_simple;
nos_symbols_and_mode2key_name = mu.nos_symbols_and_mode2key_name;
ontime_of_bar_and_beat_number = mu.ontime_of_bar_and_beat_number;
pitch_and_octave2midi_note_morphetic_pair = mu.pitch_and_octave2midi_note_morphetic_pair;
remove_duplicate_clef_changes = mu.remove_duplicate_clef_changes;
resolve_expressions = mu.resolve_expressions;
row_of_max_bar_leq_bar_arg = mu.row_of_max_bar_leq_bar_arg;
row_of_max_ontime_leq_ontime_arg = mu.row_of_max_ontime_leq_ontime_arg;
sort_points_asc = mu.sort_points_asc;
sort_points_asc_by_id = mu.sort_points_asc_by_id;
staff_voice_xml2staff_voice_json = mu.staff_voice_xml2staff_voice_json;
timelapse_object = mu.timelapse_object;
// File conversion.
comp_obj2note_point_set = mu.comp_obj2note_point_set;
split_point_set_by_staff = mu.split_point_set_by_staff;
// Keyscape.
aarden_key_profiles = mu.aarden_key_profiles;
krumhansl_and_kessler_key_profiles = mu.krumhansl_and_kessler_key_profiles;
fifth_steps_mode = mu.fifth_steps_mode;
tonic_pitch_closest = mu.tonic_pitch_closest;
// Chord labeling.
chord_templates_pbmin7ths = mu.chord_templates_pbmin7ths;
chord_lookup_pbmin7ths = mu.chord_lookup_pbmin7ths;
connect_or_not = mu.connect_or_not;
find_segment_against_template = mu.find_segment_against_template;
HarmAn_forward = mu.HarmAn_forward;
points_belonging_to_interval = mu.points_belonging_to_interval;
score_segment_against_template = mu.score_segment_against_template;
segment = mu.segment;
// Quantisation
farey = mu.farey;
farey_quantise = mu.farey_quantise;
// Array operations.
describe('#append_array', function(){
it('maps [[4], [1, 2]] to [4, 1, 2]', function(){
append_array([[4], [1, 2]]).should.eql([4, 1, 2]);
});
});
describe('#append_array_of_arrays', function(){
it('maps [["yes", 0]] to [["yes", 0]]', function(){
append_array_of_arrays(
[["yes", 0]]
).should.eql(
[["yes", 0]]
);
});
it('maps [["yes", 0], ["no", 0]] to [["yes", 0], ["no", 0]]', function(){
append_array_of_arrays(
[["yes", 0], ["no", 0]]
).should.eql(
[["yes", 0], ["no", 0]]
);
});
it('maps [[["crotchet", 0], ["crotchet", 0]]] to [["crotchet", 0], ["crotchet", 0]]', function(){
append_array_of_arrays(
[[["crotchet", 0], ["crotchet", 0]]]
).should.eql(
[["crotchet", 0], ["crotchet", 0]]
);
});
it('maps [["yes", 0], [["crotchet", 0], ["crotchet", 0], ["crotchet", 0]], ["no", 4]] to [["yes", 0], ["crotchet", 0], ["crotchet", 0], ["crotchet", 0], ["no", 4]]', function(){
append_array_of_arrays(
[
["yes", 0],
[["crotchet", 0], ["crotchet", 0], ["crotchet", 0]],
["no", 4]
]
).should.eql(
[
["yes", 0],
["crotchet", 0],
["crotchet", 0],
["crotchet", 0],
["no", 4]
]
);
});
});
describe('#array_object_index_of', function(){
it('maps array_object_index_of([{ "hello": "world", "foo": "bar" }, { "hello": "stevie", "foo": "baz" }], "stevie", "hello") to 1', function(){
var myArray = [
{
"hello": "world",
"foo": "bar"
},
{
"hello": "stevie",
"foo": "baz"
}
];
array_object_index_of(myArray, "stevie", "hello").should.equal(1);
});
it('maps array_object_index_of([{ "hello": "world", "foo": "bar" }, { "hello": "stevie", "foo": "baz" }], "stephie", "hello") to -1', function(){
var myArray = [
{
"hello": "world",
"foo": "bar"
},
{
"hello": "stevie",
"foo": "baz"
}
];
array_object_index_of(myArray, "stephie", "hello").should.equal(-1);
});
});
describe('#array_object_index_of_array', function(){
it('maps array_object_index_of_array([{ "state": [1, [-4, 0, 3]], "continuations": "blah1" }, { "state": [3, [-4, 7]], "continuations": "blah2" }], [3, [-4, 7]], "state") to 1', function(){
var myArray = [
{
"state": [1, [-4, 0, 3]],
"continuations": "blah1"
},
{
"state": [3, [-4, 7]],
"continuations": "blah2"
}
];
array_object_index_of_array(myArray, [3, [-4, 7]], "state").should.equal(1);
});
it('maps array_object_index_of_array([{ "state": [1, [-4, 0, 3]], "continuations": "blah1" }, { "state": [3, [-4, 7]], "continuations": "blah2" }], [3, [-4, 6]], "state") to -1', function(){
var myArray = [
{
"state": [1, [-4, 0, 3]],
"continuations": "blah1"
},
{
"state": [3, [-4, 7]],
"continuations": "blah2"
}
];
array_object_index_of_array(myArray, [3, [-4, 6]], "state").should.equal(-1);
});
});
describe('#array_sum', function(){
it('maps [1, -2, 3] to 2', function(){
array_sum([1, -2, 3]).should.equal(2);
});
});
describe('#copy_array_object', function(){
it('demonstrates that a change to arr2 does not affect arr1', function(){
var arr1 = { "eyes": "brown", "hair": "blue" };
var arr2 = copy_array_object(arr1);
arr2.hair = "green";
arr1.hair.should.equal("blue");
});
it('demonstrates that a change to arr4 does not affect arr3', function(){
var arr3 = ["eyes", "brown", "hair", "blue"];
var arr4 = copy_array_object(arr3);
arr4[2] = "green";
arr3[2].should.equal("hair");
});
});
describe('#cyclically_permute_array_by', function(){
it('maps cyclically_permute_array_by(["eyes", "nose", "hair"], 1) to ["nose", "hair", "eyes"]', function(){
cyclically_permute_array_by(["eyes", "nose", "hair"], 1).should.eql(["nose", "hair", "eyes"]);
});
it('maps cyclically_permute_array_by(["eyes", "nose", "hair"], 2) to ["hair", "eyes", "nose"]', function(){
cyclically_permute_array_by(["eyes", "nose", "hair"], 2).should.eql(["hair", "eyes", "nose"]);
});
it('maps cyclically_permute_array_by([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 12) to [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]', function(){
cyclically_permute_array_by([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 12).should.eql([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
});
});
describe('#factorial', function(){
it('maps factorial(4) to 24', function(){
factorial(4).should.equal(24);
});
it('maps factorial(1) to 1', function(){
factorial(1).should.equal(1);
});
it('maps factorial(0) to 1', function(){
factorial(0).should.equal(1);
});
});
describe('#binomial_coefficient', function(){
it('maps binomial_coefficient(5, 2) to 10', function(){
binomial_coefficient(5, 2).should.equal(10);
});
it('maps binomial_coefficient(100, 100) to 1', function(){
binomial_coefficient(100, 100).should.equal(1);
});
it('maps binomial_coefficient(0) to 1', function(){
binomial_coefficient(2, 5).should.eql(NaN);
});
});
describe('#Array.prototype.equals', function(){
it('maps [1, [2, 3]].equals([1, [2, 3]] to true', function(){
var a = [1, [2, 3]];
var tf = a.equals([1, [2, 3]]);
tf.should.equal(true);
});
it('maps [1, [0, 3]].equals([1, [2, 3]] to false', function(){
var a = [1, [0, 3]];
var tf = a.equals([1, [2, 3]]);
tf.should.equal(false);
});
});
describe('#Array.prototype.approx_equals', function(){
it('maps [1, [2, 3]].approx_equals([1, [2.00001, 3]] to true', function(){
var a = [1, [2, 3]];
var tf = a.approx_equals([1, [2.00001, 3]]);
tf.should.equal(true);
});
it('maps [1, [2, 3]].approx_equals([1, [2.00002, 3]] to false', function(){
var a = [1, [2, 3]];
var tf = a.approx_equals([1, [2.00002, 3]]);
tf.should.equal(false);
});
});
describe('#Array.prototype.index_item_1st_occurs', function(){
it('maps [-7, [2, 3]].index_item_1st_occurs([2, 3]] to 1', function(){
var a = [-7, [2, 3]];
var ans = a.index_item_1st_occurs([2, 3]);
ans.should.equal(1);
});
it('maps [[-7], [2, 3], { "schurrle": 7 }, 4].index_item_1st_occurs({ "schurrle": 7 }] to -1', function(){
var b = [[-7], [2, 3], { "schurrle": 7 }, 4];
var ans = b.index_item_1st_occurs({ "schurrle": 7 });
ans.should.equal(-1);
});
});
describe('#Array.prototype.index_item_1st_doesnt_occur', function(){
it('maps [[1], [1], -7].index_item_1st_doesnt_occur([1]] to 2', function(){
var a = [[1], [1], -7];
var ans = a.index_item_1st_doesnt_occur([1]);
ans.should.equal(2);
});
it('maps [{ "schurrle":7 }, 1, 1, [-7], [2, 3], 4].index_item_1st_doesnt_occur({ "schurrle": 7 }] to 0', function(){
var b = [{ "schurrle":7 }, 1, 1, [-7], [2, 3], 4];
var ans = b.index_item_1st_doesnt_occur({ "schurrle": 7 });
ans.should.equal(0);
});
});
describe('#max_argmax', function(){
it('maps max_argmax([9, -2, 4, 11, -5]) to [11, 3]', function(){
max_argmax([9, -2, 4, 11, -5]).should.eql([11, 3]);
});
});
describe('#min_argmin', function(){
it('maps min_argmin([9, -2, 4, 11, -5]) to [-5, 4]', function(){
min_argmin([9, -2, 4, 11, -5]).should.eql([-5, 4]);
});
});
describe('#multiply_array_by_constant', function(){
it('maps multiply_array_by_constant([2, 0], 5) to [10, 0]', function(){
multiply_array_by_constant([2, 0], 5).should.eql([10, 0]);
});
});
// Point-set operations.
describe('#copy_point_set', function(){
it('demonstrates that a change to arr2 does not affect arr1', function(){
var arr1 = [[3, 0, 3], [-2, 2, 1], [4, -1, -2], [3, 0, 3]];;
var arr2 = copy_array_object(arr1);
arr2[1][0] = 3;
arr1[1][0].should.equal(-2);
});
});
describe('#count_rows', function(){
it('maps count_rows([[0, 60], [0, 59], [0, 60]]) to [[[0, 59], [0, 60]], [1, 2]]', function(){
count_rows([[0, 60], [0, 59], [0, 60]]).should.eql([[[0, 59], [0, 60]], [1, 2]]);
});
it('maps count_rows([[3, 0, 3], [-2, 2, 1], [3.000007, 0, 3]]) to [[[-2, 2, 1], [3, 0, 3], [3.000007, 0, 3]], [[1], [1], [1]]]', function(){
count_rows([[3, 0, 3], [-2, 2, 1], [3.000007, 0, 3]]).should.eql([[[-2, 2, 1], [3, 0, 3], [3.000007, 0, 3]], [1, 1, 1]]);
});
it('maps count_rows([[3, 0, 3], [-2, 2, 1], [3.000007, 0, 3]], undefined, true) to [[[-2, 2, 1], [3, 0, 3]], [[1], [0, 2]]]', function(){
count_rows([[3, 0, 3], [-2, 2, 1], [3.000007, 0, 3]], undefined, true).should.eql([[[-2, 2, 1], [3, 0, 3]], [1, 2]]);
});
});
describe('#count_rows', function(){
it('maps count_rows([[0, 2, 60], [0, 1, 59], [0, 1, 60]], 1) to [[[0, 59], [0, 60]], [1, 3]]', function(){
count_rows([[0, 2, 60], [0, 1, 59], [0, 1, 60]], 1).should.eql([[[0, 59], [0, 60]], [1, 3]]);
});
it('maps count_rows([[3, 0, 4], [-2, 2, 1], [3.000007, 0, 3]], 2) to [[[-2, 2], [3, 0], [3.000007, 0]], [1, 4, 3]]', function(){
count_rows([[3, 0, 4], [-2, 2, 1], [3.000007, 0, 3]], 2).should.eql([[[-2, 2], [3, 0], [3.000007, 0]], [1, 4, 3]]);
});
it('maps count_rows([[3, 0, 4], [-2, 2, 1], [3.000007, 0, 3]], 2, true) to [[[-2, 2], [3, 0]], [1, 7]]', function(){
count_rows([[3, 0, 4], [-2, 2, 1], [3.000007, 0, 3]], 2, true).should.eql([[[-2, 2], [3, 0]], [1, 7]]);
});
});
describe('#index_point_set', function(){
it('maps index_point_set([[3, 0, 3], [-2, 2, 1], [4, -1, -2], [3, 0, 3]]) to [[3, 0, 3, 0], [-2, 2, 1, 1], [4, -1, -2, 2], [3, 0, 3, 3]]', function(){
index_point_set([[3, 0, 3], [-2, 2, 1], [4, -1, -2], [3, 0, 3]]).should.eql([[3, 0, 3, 0], [-2, 2, 1, 1], [4, -1, -2, 2], [3, 0, 3, 3]]);
});
});
describe('#get_unique', function(){
it('maps get_unique(["h", 1, "h", 2, "g", 2]) to ["h", 1, 2, "g"]', function(){
get_unique(["h", 1, "h", 2, "g", 2]).should.eql(["h", 1, 2, "g"]);
});
});
describe('#lex_more', function(){
it('maps lex_more([2, 7, 1], [2, 4, 2]) to 1', function(){
lex_more([2, 7, 1], [2, 4, 2]).should.equal(1);
});
});
describe('#lex_more', function(){
it('maps lex_more([2, -7, 1], [2, 4, 2]) to -1', function(){
lex_more([2, -7, 1], [2, 4, 2]).should.equal(-1);
});
});
describe('#restrict_point_set_in_nth_to_xs', function(){
it('maps restrict_point_set_in_nth_to_xs([[2, 7], [3, 0], [-7, 3]], 1, [3, 7]) to [[2, 7], [-7, 3]]', function(){
restrict_point_set_in_nth_to_xs([[2, 7], [3, 0], [-7, 3]], 1, [3, 7]).should.eql([[2, 7], [-7, 3]]);
});
});
describe('#sort_rows', function(){
it('maps sort_rows([[3, 0, 3], [-2, 2, 1], [4, -1, -2], [3, 0, 3]]) to [[[-2, 2, 1], [3, 0, 3], [3, 0, 3], [4, -1, -2]], [1, 0, 3, 2]]', function(){
sort_rows([[3, 0, 3], [-2, 2, 1], [4, -1, -2], [3, 0, 3]]).should.eql([[[-2, 2, 1], [3, 0, 3], [3, 0, 3], [4, -1, -2]], [1, 0, 3, 2]]);
});
});
describe('#subtract_two_arrays', function(){
it('maps subtract_two_arrays([4, 7, -3], [8, -2, -3]) to [-4, 9, 0]', function(){
subtract_two_arrays([4, 7, -3], [8, -2, -3]).should.eql([-4, 9, 0]);
});
});
describe('#unique_rows', function(){
it('maps unique_rows([[3, 0, 3], [-2, 2, 1], [4, -1, -2], [3, 0, 3]]) to [[[-2, 2, 1], [3, 0, 3], [4, -1, -2]], [[1], [0, 3], [2]]]', function(){
unique_rows([[3, 0, 3], [-2, 2, 1], [4, -1, -2], [3, 0, 3]]).should.eql([[[-2, 2, 1], [3, 0, 3], [4, -1, -2]], [[1], [0, 3], [2]]]);
});
it('maps unique_rows([[3, 0, 3], [-2, 2, 1], [3.000007, 0, 3]]) to [[[-2, 2, 1], [3, 0, 3], [3.000007, 0, 3]], [[1], [0], [2]]]', function(){
unique_rows([[3, 0, 3], [-2, 2, 1], [3.000007, 0, 3]]).should.eql([[[-2, 2, 1], [3, 0, 3], [3.000007, 0, 3]], [[1], [0], [2]]]);
});
it('maps unique_rows([[3, 0, 3], [-2, 2, 1], [3.000007, 0, 3]], true) to [[[-2, 2, 1], [3, 0, 3]], [[1], [0, 2]]]', function(){
unique_rows([[3, 0, 3], [-2, 2, 1], [3.000007, 0, 3]], true).should.eql([[[-2, 2, 1], [3, 0, 3]], [[1], [0, 2]]]);
});
});
// Stats sampling.
describe('#choose_one', function(){
it('maps choose_one([3, 0, 1]) to one of 3, 0, or 1', function(){
var ans = choose_one([3, 0, 1]);
switch (ans){
case 0:
ans.should.equal(0);
break;
case 1:
ans.should.equal(1);
break;
case 3:
ans.should.equal(3);
break;
}
});
it('maps choose_one([3, 0, 1], [0.33, 0.67, 1]) to one of 3, 0, or 1', function(){
var ans = choose_one([3, 0, 1], [0.33, 0.67, 1]);
switch (ans){
case 0:
ans.should.equal(0);
break;
case 1:
ans.should.equal(1);
break;
case 3:
ans.should.equal(3);
break;
}
});
it('maps choose_one([3, 34], [0, 1]) to 34', function(){
var ans = choose_one([3, 34], [0, 1]);
ans.should.equal(34);
});
it('maps choose_one([3, 34], [1, 0]) to 3', function(){
var ans = choose_one([3, 34], [1, 0]);
ans.should.equal(3);
});
});
describe('#corr', function(){
it('maps corr([3, 0.5, -1, -1.5, -1.4], [-2.5, 0.1, 1, 1.8, 2]) to -0.991389', function(){
var r = corr([3, 0.5, -1, -1.5, -1.4], [-2.5, 0.1, 1, 1.8, 2]);
r = Math.round(r*1000000)/1000000;
r.should.equal(-0.991389);
});
});
describe('#get_random_arbitrary', function(){
it('maps get_random_arbitrary(-2.3, 4) to a random number -2.3 <= x < 4', function(){
var ans = get_random_arbitrary(-2.3, 4);
if (ans >= -2.3 && ans < 4){
ans.should.equal(ans);
}
else {
throw "Error in get_random_arbitrary: function is not performing as described.";
}
});
});
describe('#get_random_int', function(){
it('maps get_random_int(-2, 1) to a random number -2 <= x < 1', function(){
var ans = get_random_int(-2, 1);
switch (ans){
case -2:
ans.should.equal(-2);
break;
case -1:
ans.should.equal(-1);
break;
case 0:
ans.should.equal(0);
break;
}
});
});
describe('#get_random_int_inclusive', function(){
it('maps get_random_int_inclusive(-2, 1) to a random number -2 <= x <= 1', function(){
var ans = get_random_int_inclusive(-2, 1);
switch (ans){
case -2:
ans.should.equal(-2);
break;
case -1:
ans.should.equal(-1);
break;
case 0:
ans.should.equal(0);
break;
case 1:
ans.should.equal(1);
break;
}
});
});
describe('#mean', function(){
it('maps mean([3, 0, 3]) to 2', function(){
mean([3, 0, 3]).should.equal(2);
});
});
describe('#median', function(){
it('maps median([1.5, 0, 3]) to 1.5', function(){
median([1.5, 0, 3]).should.equal(1.5);
});
});
describe('#median', function(){
it('maps median([1.5, 0, 3, 2]) to 1.75', function(){
median([1.5, 0, 3, 2]).should.equal(1.75);
});
});
describe('#std', function(){
it('maps std([727.7, 1086.5, 1091.0, 1361.3, 1490.5, 1956.1]) to 420.96', function(){
(Math.round(100*std([727.7, 1086.5, 1091.0, 1361.3, 1490.5, 1956.1]))/100).should.equal(420.96);
});
});
describe('#entropy', function(){
it('maps entropy([1]) to 0', function(){
entropy([1]).should.equal(0);
});
});
describe('#entropy', function(){
it('maps entropy([0.5, 0.5]) to 1', function(){
entropy([0.5, 0.5]).should.equal(1);
});
});
describe('#entropy', function(){
it('maps entropy([0.25, 0.25, 0.25, 0.25]) to 2', function(){
entropy([0.25, 0.25, 0.25, 0.25]).should.equal(2);
});
});
describe('#entropy', function(){
it('maps entropy([0.25, 0.35, 0.25, 0.15]) to 1.9406', function(){
(Math.round(10000*entropy([0.25, 0.35, 0.25, 0.15]))/10000).should.equal(1.9406);
});
});
describe('#skewness', function(){
it('maps skewness([7.7, 10.5, 10.0, 13.3, 14.5, 19.1]) to 0.53', function(){
(Math.round(100*skewness([7.7, 10.5, 10.0, 13.3, 14.5, 19.1]))/100).should.equal(0.53);
});
});
describe('#median_skewness', function(){
it('maps median_skewness([7.7, 10.5, 10.0, 13.3, 14.5, 19.1]) to 0.50', function(){
(Math.round(100*median_skewness([7.7, 10.5, 10.0, 13.3, 14.5, 19.1]))/100).should.equal(0.50);
});
});
describe('#excess_kurtosis', function(){
it('maps excess_kurtosis([7.7, 10.5, 10.0, 13.3, 14.5, 19.1]) to -0.75', function(){
(Math.round(100*excess_kurtosis([7.7, 10.5, 10.0, 13.3, 14.5, 19.1]))/100).should.equal(-0.75);
});
});
describe('#mod', function(){
it('maps mod(-8, 10) to 2', function(){
mod(-8, 10).should.equal(2);
});
});
describe('#sample_without_replacement', function(){
it('maps sample_without_replacement([-2, 71], 1) to either [-2] or [71]', function(){
var ans = sample_without_replacement([-2, 71], 1);
switch (ans[0]){
case -2:
ans.should.eql([-2]);
break;
case 71:
ans.should.eql([71]);
break;
}
});
it('maps sample_without_replacement([-2, 71], 2) to either [-2, 71] or [71, -2]', function(){
var ans = sample_without_replacement([-2, 71], 2);
switch (ans[0]){
case -2:
ans.should.eql([-2, 71]);
break;
case 71:
ans.should.eql([71, -2]);
break;
}
});
it('maps sample_without_replacement([-2, 71], 3) to undefined', function(){
var ans = sample_without_replacement([-2, 71], 3)
should.equal(ans, undefined)
});
it('maps sample_without_replacement([], 1) to undefined', function(){
var ans = sample_without_replacement([], 1);
should.equal(ans, undefined)
});
});
// Interpolation.
describe('#index_1st_element_gt', function(){
it('maps index_1st_element_gt(0, [-2, -2, -1, 0, 0, 11, 14, 14, 14]) to 5', function(){
index_1st_element_gt(0, [-2, -2, -1, 0, 0, 11, 14, 14, 14]).should.equal(5);
});
});
// Projection.
describe('#lex_less_or_equal_triple', function(){
it('maps lex_less_or_equal_triple([2, 1, 7], [3, 1, -3], [5, 2, 4], 3) to 0', function(){
lex_less_or_equal_triple([2, 1, 7], [3, 1, -3], [5, 2, 4], 3).should.equal(0);
});
it('maps lex_less_or_equal_triple([1, 1, 7], [3, 1, -3], [5, 2, 4], 3) to 1', function(){
lex_less_or_equal_triple([1, 1, 7], [3, 1, -3], [5, 2, 4], 3).should.equal(1);
});
it('maps lex_less_or_equal_triple([1, 1, 7], [3, 1, -3], [4, 1, 4], 3) to -1', function(){
lex_less_or_equal_triple([1, 1, 7], [3, 1, -3], [4, 1, 4], 3).should.equal(-1);
});
});
describe('#lex_less_or_equal', function(){
it('maps lex_less_or_equal([2, 1, 7], [2, 1, 9]) to 1', function(){
lex_less_or_equal([2, 1, 7], [2, 1, 9], 3).should.equal(1);
});
it('maps lex_less_or_equal([2, 1, 7], [2, -1, 9]) to -1', function(){
lex_less_or_equal([2, 1, 7], [2, -1, 9], 3).should.equal(-1);
});
it('maps lex_less_or_equal([1, 1, 7], [1, 1, 7]) to 0', function(){
lex_less_or_equal([1, 1, 7], [1, 1, 7]).should.equal(0);
});
});
describe('#orthogonal_projection_not_unique_equalp', function(){
it('maps orthogonal_projection_not_unique_equalp([[2, 4, -1, 6, 9], [0, 0, 4, 2, -7], [-3, -2, -1, -1, 1], [12, 0, -7, 5, 3], [1, 2, 3, 4, 3], [1, 2, 5, 4, 5]], [1, 1, 0, 1, 0]) to [[2, 4, 6], [0, 0, 2], [-3, -2, -1], [12, 0, 5], [1, 2, 4], [1, 2, 4]]', function(){
orthogonal_projection_not_unique_equalp([[2, 4, -1, 6, 9], [0, 0, 4, 2, -7], [-3, -2, -1, -1, 1], [12, 0, -7, 5, 3], [1, 2, 3, 4, 3], [1, 2, 5, 4, 5]], [1, 1, 0, 1, 0]).should.eql([[2, 4, 6], [0, 0, 2], [-3, -2, -1], [12, 0, 5], [1, 2, 4], [1, 2, 4]]);
});
});
describe('#maximal_translatable_pattern', function(){
it('maps maximal_translatable_pattern([12, 2, 0], [[0, 69, 0.5], [0.5, 66, 0.5], [1, 67, 1], [2, 65, 1], [3, 66, 0.5], [3.5, 64, 0.5], [4, 62, 2], [5, 55, 1], [5, 59, 1], [5, 61, 1], [6, 63, 0.5], [6.5, 64, 0.5], [7, 55, 1], [7, 56, 1], [7, 61, 1], [7, 65, 1], [8, 55, 1], [8, 57, 1], [8, 61, 1], [8, 66, 1], [9, 51, 1], [9, 67, 0.5], [9.5, 70, 0.5], [10, 55, 1], [10, 60, 1], [10, 69, 2], [11, 51, 1], [12, 50, 1], [12, 71, 0.5], [12.5, 68, 0.5], [13, 57, 1], [13, 60, 1], [13, 62, 1], [13, 69, 1], [14, 60, 1], [14, 62, 1], [14, 65, 1], [14, 67, 1], [15, 68, 0.5], [15.5, 66, 0.5], [16, 57, 1], [16, 61, 1], [16, 63, 1], [16, 64, 2], [17, 57, 1], [17, 59, 1], [17, 63, 1], [18, 65, 0.5], [18.5, 66, 0.5], [19, 57, 1], [19, 58, 1], [19, 63, 1], [19, 67, 1], [20, 57, 1], [20, 59, 1], [20, 63, 1], [20, 68, 1]], 3, 57) to [[[0, 69, 0.5], [0.5, 66, 0.5], [1, 67, 1], [2, 65, 1], [3, 66, 0.5], [3.5, 64, 0.5], [4, 62, 2], [5, 55, 1], [5, 61, 1], [6, 63, 0.5], [6.5, 64, 0.5], [7, 55, 1], [7, 56, 1], [7, 61, 1], [7, 65, 1], [8, 55, 1], [8, 57, 1], [8, 61, 1], [8, 66, 1]], [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]]', function(){
maximal_translatable_pattern([12, 2, 0], [[0, 69, 0.5], [0.5, 66, 0.5], [1, 67, 1], [2, 65, 1], [3, 66, 0.5], [3.5, 64, 0.5], [4, 62, 2], [5, 55, 1], [5, 59, 1], [5, 61, 1], [6, 63, 0.5], [6.5, 64, 0.5], [7, 55, 1], [7, 56, 1], [7, 61, 1], [7, 65, 1], [8, 55, 1], [8, 57, 1], [8, 61, 1], [8, 66, 1], [9, 51, 1], [9, 67, 0.5], [9.5, 70, 0.5], [10, 55, 1], [10, 60, 1], [10, 69, 2], [11, 51, 1], [12, 50, 1], [12, 71, 0.5], [12.5, 68, 0.5], [13, 57, 1], [13, 60, 1], [13, 62, 1], [13, 69, 1], [14, 60, 1], [14, 62, 1], [14, 65, 1], [14, 67, 1], [15, 68, 0.5], [15.5, 66, 0.5], [16, 57, 1], [16, 61, 1], [16, 63, 1], [16, 64, 2], [17, 57, 1], [17, 59, 1], [17, 63, 1], [18, 65, 0.5], [18.5, 66, 0.5], [19, 57, 1], [19, 58, 1], [19, 63, 1], [19, 67, 1], [20, 57, 1], [20, 59, 1], [20, 63, 1], [20, 68, 1]], 3, 57).should.eql([[[0, 69, 0.5], [0.5, 66, 0.5], [1, 67, 1], [2, 65, 1], [3, 66, 0.5], [3.5, 64, 0.5], [4, 62, 2], [5, 55, 1], [5, 61, 1], [6, 63, 0.5], [6.5, 64, 0.5], [7, 55, 1], [7, 56, 1], [7, 61, 1], [7, 65, 1], [8, 55, 1], [8, 57, 1], [8, 61, 1], [8, 66, 1]], [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]]);
});
});
describe('#intersection', function(){
it('maps intersection([[1, 4], [2, -2]], [[-2, 3], [2, -2], [4, 1]]) to [[2, -2]]', function(){
intersection([[1, 4], [2, -2]], [[-2, 3], [2, -2], [4, 1]]).should.eql([[2, -2]]);
});
});
describe('#intersection_hash', function(){
it('maps intersection_hash([[1, 4], [2, -2]], { "-2,3": 0, "2,-2": 1, "4,1": 2 }) to [[2, -2]]', function(){
intersection_hash([[1, 4], [2, -2]], { "-2,3": 0, "2,-2": 1, "4,1": 2 }).should.eql([[2, -2]]);
});
});
describe('#siar', function(){
it('maps siar([[0, 64], [1+1/3, 62], [1+2/3, 68], [3, 66]], 1) to [{ "vector": [1+2/3, 4], "MTP": [[0, 64], [1+1/3, 62]] }]', function(){
const result = siar([[0, 64], [1 + 1/3, 62], [1 + 2/3, 68], [3, 66]], 1)
// Now do manual checks with .closeTo for floating-point numbers
expect(result).to.have.lengthOf(1)
// Check the "vector" array
expect(result[0]).to.have.property('vector')
expect(result[0].vector).to.have.lengthOf(2)
expect(result[0].vector[0]).to.be.closeTo(1 + 2/3, 1e-5)
expect(result[0].vector[1]).to.be.closeTo(4, 1e-5)
// Check the "MTP" property
expect(result[0]).to.have.property('MTP')
expect(result[0].MTP).to.have.lengthOf(2)
expect(result[0].MTP[0][0]).to.be.closeTo(0, 1e-5)
expect(result[0].MTP[0][1]).to.be.closeTo(64, 1e-5)
expect(result[0].MTP[1][0]).to.be.closeTo(1 + 1/3, 1e-5)
expect(result[0].MTP[1][1]).to.be.closeTo(62, 1e-5)
});
it('maps siar([[0, 69, 0.5], [0.5, 66, 0.5], [1, 67, 1], [2, 65, 1], [3, 66, 0.5], [3.5, 64, 0.5], [4, 62, 2], [5, 55, 1], [5, 59, 1], [5, 61, 1], [6, 63, 0.5], [6.5, 64, 0.5], [7, 55, 1], [7, 56, 1], [7, 61, 1], [7, 65, 1], [8, 55, 1], [8, 57, 1], [8, 61, 1], [8, 66, 1], [9, 51, 1], [9, 67, 0.5], [9.5, 70, 0.5], [10, 55, 1], [10, 60, 1], [10, 69, 2], [11, 51, 1], [12, 50, 1], [12, 71, 0.5], [12.5, 68, 0.5], [13, 57, 1], [13, 60, 1], [13, 62, 1], [13, 69, 1], [14, 60, 1], [14, 62, 1], [14, 65, 1], [14, 67, 1], [15, 68, 0.5], [15.5, 66, 0.5], [16, 57, 1], [16, 61, 1], [16, 63, 1], [16, 64, 2], [17, 57, 1], [17, 59, 1], [17, 63, 1], [18, 65, 0.5], [18.5, 66, 0.5], [19, 57, 1], [19, 58, 1], [19, 63, 1], [19, 67, 1], [20, 57, 1], [20, 59, 1], [20, 63, 1], [20, 68, 1]]) to [{"vector":[12,2,0],"MTP":[[0,69,0.5],[0.5,66,0.5],[1,67,1],[2,65,1],[3,66,0.5],[3.5,64,0.5],[4,62,2],[5,55,1],[5,61,1],[6,63,0.5],[6.5,64,0.5],[7,55,1],[7,56,1],[7,61,1],[7,65,1],[8,55,1],[8,57,1],[8,61,1],[8,66,1]]},{"vector":[1,5,0],"MTP":[[7,56,1],[7,61,1],[13,57,1],[13,60,1],[13,62,1],[19,58,1],[19,63,1]]},{"vector":[1,-4,0],"MTP":[[7,61,1],[7,65,1],[8,55,1],[10,55,1],[13,69,1],[16,61,1],[16,63,1],[19,63,1],[19,67,1]]},{"vector":[9,2,0],"MTP":[[6.5,64,0.5],[7,55,1],[7,61,1],[8,55,1],[8,57,1],[8,61,1],[10,55,1]]},{"vector":[3,0,0],"MTP":[[3.5,64,0.5],[5,55,1],[5,61,1],[7,55,1],[10,60,1],[13,57,1],[15.5,66,0.5],[16,57,1],[16,63,1],[17,57,1],[17,59,1],[17,63,1]]},{"vector":[11,2,0],"MTP":[[5,55,1],[5,59,1],[5,61,1],[8,55,1],[8,61,1]]},{"vector":[2,6,0],"MTP":[[5,55,1],[5,59,1],[11,51,1],[17,57,1]]},{"vector":[3,2,0],"MTP":[[5,55,1],[5,59,1],[10,55,1],[10,60,1],[16,61,1],[17,57,1]]},{"vector":[12,4,0],"MTP":[[5,55,1],[5,59,1],[8,55,1]]},{"vector":[14,8,0],"MTP":[[5,55,1],[5,59,1]]},{"vector":[15,4,0],"MTP":[[5,55,1],[5,59,1]]},{"vector":[9,-4,0],"MTP":[[7,61,1],[7,65,1],[8,61,1],[9.5,70,0.5]]},{"vector":[10,-2,0],"MTP":[[7,61,1],[7,65,1]]},{"vector":[13,-2,0],"MTP":[[1,67,1],[7,61,1],[7,65,1]]},{"vector":[8,0,0],"MTP":[[8,57,1],[8,61,1]]},{"vector":[11,6,0],"MTP":[[5,55,1],[8,57,1],[8,61,1],[9,51,1]]},{"vector":[1,2,0],"MTP":[[7,55,1],[13,60,1],[16,57,1],[16,61,1],[19,57,1]]},{"vector":[3,6,0],"MTP":[[5,55,1],[6.5,64,0.5],[13,57,1],[16,57,1],[16,61,1],[17,57,1]]},{"vector":[4,2,0],"MTP":[[10,60,1],[13,57,1],[16,57,1],[16,61,1]]},{"vector":[2,4,0],"MTP":[[5,61,1],[17,59,1],[17,63,1]]},{"vector":[3,-4,0],"MTP":[[2,65,1],[5,59,1],[5,61,1],[8,55,1],[14,67,1],[16,61,1],[17,63,1]]},{"vector":[8,1,0],"MTP":[[5,59,1],[5,61,1]]},{"vector":[9,1,0],"MTP":[[5,59,1],[5,61,1],[7,56,1]]},{"vector":[9,6,0],"MTP":[[5,59,1],[5,61,1],[7,55,1],[8,57,1],[11,51,1]]},{"vector":[12,-2,0],"MTP":[[5,59,1],[5,61,1],[7,65,1],[8,61,1]]},{"vector":[15,-2,0],"MTP":[[2,65,1],[5,59,1],[5,61,1]]},{"vector":[5,5,0],"MTP":[[5,55,1],[8,55,1],[8,57,1],[14,62,1]]},{"vector":[6,5,0],"MTP":[[7,55,1],[8,55,1],[8,57,1],[13,62,1]]},{"vector":[6,10,0],"MTP":[[8,55,1],[8,57,1],[13,57,1]]},{"vector":[8,6,0],"MTP":[[8,55,1],[8,57,1],[9,51,1],[11,51,1]]},{"vector":[1,0,0],"MTP":[[7,55,1],[7,61,1],[13,60,1],[13,62,1],[16,57,1],[16,63,1],[19,57,1],[19,63,1]]},{"vector":[3,1,0],"MTP":[[13,60,1],[13,62,1],[14,62,1],[16,57,1]]},{"vector":[4,-3,0],"MTP":[[13,60,1],[13,62,1]]},{"vector":[7,-3,0],"MTP":[[7,65,1],[10,60,1],[13,60,1],[13,62,1]]},{"vector":[0,5,0],"MTP":[[7,56,1],[8,61,1],[10,55,1],[13,57,1],[14,60,1],[14,62,1],[19,58,1],[20,63,1]]},{"vector":[2,1,0],"MTP":[[5,55,1],[14,60,1],[14,62,1],[17,57,1]]},{"vector":[3,-3,0],"MTP":[[0,69,0.5],[3,66,0.5],[10,60,1],[12,71,0.5],[13,60,1],[14,60,1],[14,62,1],[15,68,0.5],[16,61,1]]},{"vector":[6,-3,0],"MTP":[[7,65,1],[10,60,1],[13,60,1],[14,60,1],[14,62,1]]},{"vector":[2,-4,0],"MTP":[[5,59,1],[7,55,1],[14,65,1],[14,67,1]]},{"vector":[3,-8,0],"MTP":[[13,69,1],[14,65,1],[14,67,1]]},{"vector":[6,-8,0],"MTP":[[2,65,1],[5,59,1],[7,65,1],[14,65,1],[14,67,1]]},{"vector":[4,-4,0],"MTP":[[5,55,1],[7,55,1],[16,61,1],[16,63,1]]},{"vector":[3,-1,0],"MTP":[[7,56,1],[7,61,1],[9,51,1],[13,62,1],[14,60,1]]},{"vector":[13,7,0],"MTP":[[7,56,1],[7,61,1]]},{"vector":[2,-6,0],"MTP":[[5,61,1],[8,61,1],[8,66,1],[14,67,1],[17,63,1]]},{"vector":[11,-3,0],"MTP":[[2,65,1],[8,61,1],[8,66,1]]},{"vector":[9,3,0],"MTP":[[5,59,1],[10,55,1],[10,60,1]]},{"vector":[10,8,0],"MTP":[[7,55,1],[10,55,1],[10,60,1]]}]', function(){
siar([[0, 69, 0.5], [0.5, 66, 0.5], [1, 67, 1], [2, 65, 1], [3, 66, 0.5], [3.5, 64, 0.5], [4, 62, 2], [5, 55, 1], [5, 59, 1], [5, 61, 1], [6, 63, 0.5], [6.5, 64, 0.5], [7, 55, 1], [7, 56, 1], [7, 61, 1], [7, 65, 1], [8, 55, 1], [8, 57, 1], [8, 61, 1], [8, 66, 1], [9, 51, 1], [9, 67, 0.5], [9.5, 70, 0.5], [10, 55, 1], [10, 60, 1], [10, 69, 2], [11, 51, 1], [12, 50, 1], [12, 71, 0.5], [12.5, 68, 0.5], [13, 57, 1], [13, 60, 1], [13, 62, 1], [13, 69, 1], [14, 60, 1], [14, 62, 1], [14, 65, 1], [14, 67, 1], [15, 68, 0.5], [15.5, 66, 0.5], [16, 57, 1], [16, 61, 1], [16, 63, 1], [16, 64, 2], [17, 57, 1], [17, 59, 1], [17, 63, 1], [18, 65, 0.5], [18.5, 66, 0.5], [19, 57, 1], [19, 58, 1], [19, 63, 1], [19, 67, 1], [20, 57, 1], [20, 59, 1], [20, 63, 1], [20, 68, 1]]).should.eql([{"vector":[12,2,0],"MTP":[[0,69,0.5],[0.5,66,0.5],[1,67,1],[2,65,1],[3,66,0.5],[3.5,64,0.5],[4,62,2],[5,55,1],[5,61,1],[6,63,0.5],[6.5,64,0.5],[7,55,1],[7,56,1],[7,61,1],[7,65,1],[8,55,1],[8,57,1],[8,61,1],[8,66,1]]},{"vector":[1,5,0],"MTP":[[7,56,1],[7,61,1],[13,57,1],[13,60,1],[13,62,1],[19,58,1],[19,63,1]]},{"vector":[1,-4,0],"MTP":[[7,61,1],[7,65,1],[8,55,1],[10,55,1],[13,69,1],[16,61,1],[16,63,1],[19,63,1],[19,67,1]]},{"vector":[9,2,0],"MTP":[[6.5,64,0.5],[7,55,1],[7,61,1],[8,55,1],[8,57,1],[8,61,1],[10,55,1]]},{"vector":[3,0,0],"MTP":[[3.5,64,0.5],[5,55,1],[5,61,1],[7,55,1],[10,60,1],[13,57,1],[15.5,66,0.5],[16,57,1],[16,63,1],[17,57,1],[17,59,1],[17,63,1]]},{"vector":[11,2,0],"MTP":[[5,55,1],[5,59,1],[5,61,1],[8,55,1],[8,61,1]]},{"vector":[2,6,0],"MTP":[[5,55,1],[5,59,1],[11,51,1],[17,57,1]]},{"vector":[3,2,0],"MTP":[[5,55,1],[5,59,1],[10,55,1],[10,60,1],[16,61,1],[17,57,1]]},{"vector":[12,4,0],"MTP":[[5,55,1],[5,59,1],[8,55,1]]},{"vector":[14,8,0],"MTP":[[5,55,1],[5,59,1]]},{"vector":[15,4,0],"MTP":[[5,55,1],[5,59,1]]},{"vector":[9,-4,0],"MTP":[[7,61,1],[7,65,1],[8,61,1],[9.5,70,0.5]]},{"vector":[10,-2,0],"MTP":[[7,61,1],[7,65,1]]},{"vector":[13,-2,0],"MTP":[[1,67,1],[7,61,1],[7,65,1]]},{"vector":[8,0,0],"MTP":[[8,57,1],[8,61,1]]},{"vector":[11,6,0],"MTP":[[5,55,1],[8,57,1],[8,61,1],[9,51,1]]},{"vector":[1,2,0],"MTP":[[7,55,1],[13,60,1],[16,57,1],[16,61,1],[19,57,1]]},{"vector":[3,6,0],"MTP":[[5,55,1],[6.5,64,0.5],[13,57,1],[16,57,1],[16,61,1],[17,57,1]]},{"vector":[4,2,0],"MTP":[[10,60,1],[13,57,1],[16,57,1],[16,61,1]]},{"vector":[2,4,0],"MTP":[[5,61,1],[17,59,1],[17,63,1]]},{"vector":[3,-4,0],"MTP":[[2,65,1],[5,59,1],[5,61,1],[8,55,1],[14,67,1],[16,61,1],[17,63,1]]},{"vector":[8,1,0],"MTP":[[5,59,1],[5,61,1]]},{"vector":[9,1,0],"MTP":[[5,59,1],[5,61,1],[7,56,1]]},{"vector":[9,6,0],"MTP":[[5,59,1],[5,61,1],[7,55,1],[8,57,1],[11,51,1]]},{"vector":[12,-2,0],"MTP":[[5,59,1],[5,61,1],[7,65,1],[8,61,1]]},{"vector":[15,-2,0],"MTP":[[2,65,1],[5,59,1],[5,61,1]]},{"vector":[5,5,0],"MTP":[[5,55,1],[8,55,1],[8,57,1],[14,62,1]]},{"vector":[6,5,0],"MTP":[[7,55,1],[8,55,1],[8,57,1],[13,62,1]]},{"vector":[6,10,0],"MTP":[[8,55,1],[8,57,1],[13,57,1]]},{"vector":[8,6,0],"MTP":[[8,55,1],[8,57,1],[9,51,1],[11,51,1]]},{"vector":[1,0,0],"MTP":[[7,55,1],[7,61,1],[13,60,1],[13,62,1],[16,57,1],[16,63,1],[19,57,1],[19,63,1]]},{"vector":[3,1,0],"MTP":[[13,60,1],[13,62,1],[14,62,1],[16,57,1]]},{"vector":[4,-3,0],"MTP":[[13,60,1],[13,62,1]]},{"vector":[7,-3,0],"MTP":[[7,65,1],[10,60,1],[13,60,1],[13,62,1]]},{"vector":[0,5,0],"MTP":[[7,56,1],[8,61,1],[10,55,1],[13,57,1],[14,60,1],[14,62,1],[19,58,1],[20,63,1]]},{"vector":[2,1,0],"MTP":[[5,55,1],[14,60,1],[14,62,1],[17,57,1]]},{"vector":[3,-3,0],"MTP":[[0,69,0.5],[3,66,0.5],[10,60,1],[12,71,0.5],[13,60,1],[14,60,1],[14,62,1],[15,68,0.5],[16,61,1]]},{"vector":[6,-3,0],"MTP":[[7,65,1],[10,60,1],[13,60,1],[14,60,1],[14,62,1]]},{"vector":[2,-4,0],"MTP":[[5,59,1],[7,55,1],[14,65,1],[14,67,1]]},{"vector":[3,-8,0],"MTP":[[13,69,1],[14,65,1],[14,67,1]]},{"vector":[6,-8,0],"MTP":[[2,65,1],[5,59,1],[7,65,1],[14,65,1],[14,67,1]]},{"vector":[4,-4,0],"MTP":[[5,55,1],[7,55,1],[16,61,1],[16,63,1]]},{"vector":[3,-1,0],"MTP":[[7,56,1],[7,61,1],[9,51,1],[13,62,1],[14,60,1]]},{"vector":[13,7,0],"MTP":[[7,56,1],[7,61,1]]},{"vector":[2,-6,0],"MTP":[[5,61,1],[8,61,1],[8,66,1],[14,67,1],[17,63,1]]},{"vector":[11,-3,0],"MTP":[[2,65,1],[8,61,1],[8,66,1]]},{"vector":[9,3,0],"MTP":[[5,59,1],[10,55,1],[10,60,1]]},{"vector":[10,8,0],"MTP":[[7,55,1],[10,55,1],[10,60,1]]}])
});
});
describe('#translators', function(){
it('maps translators([[10, 8], [12, 8], [12, 10], [13, 9]], [[5, 6], [5, 7], [6, 7], [7, 8], [8, 5], [8, 7], [8, 9], [9, 7], [9, 8], [10, 8], [12, 6], [12, 8], [12, 10], [13, 5], [13, 9], [14, 7], [15, 5], [15, 7], [15, 10], [16, 6]]) to [[-4, -1], [0, 0], [3, -3]]', function(){
translators([[10, 8], [12, 8], [12, 10], [13, 9]], [[5, 6], [5, 7], [6, 7], [7, 8], [8, 5], [8, 7], [8, 9], [9, 7], [9, 8], [10, 8], [12, 6], [12, 8], [12, 10], [13, 5], [13, 9], [14, 7], [15, 5], [15, 7], [15, 10], [16, 6]]).should.eql([[-4, -1], [0, 0], [3, -3]]);
});
});
describe('#cardinality_score', function(){
it('maps cardinality_score([[1, 1], [1, 3], [1, 4], [2, 2], [3, 1], [4, 1], [4, 4]], [[3, 4], [3, 6], [3, 7], [4, 2], [5, 4], [5, 5], [6, 7], [7, 1]]) to [0.625, [2, 2]]', function(){
cardinality_score([[1, 1], [1, 3], [1, 4], [2, 2], [3, 1], [4, 1], [4, 4]], [[3, 4], [3, 6], [3, 7], [4, 2], [5, 4], [5, 5], [6, 7], [7, 1]]).should.eql([0.625, [2, 3]]);
});
});
// String operations.
describe('#locations', function(){
it('maps locations("z", "hi, how high is it?") to []', function(){
locations("z", "hi, how high is it?").should.eql([]);
});
it('maps locations("i", "hi, how high is it?") to [1, 9, 13, 16]', function(){
locations("i", "hi, how high is it?").should.eql([1, 9, 13, 16]);
});
});
describe('#my_last_string', function(){
it('maps my_last_string("F#5") to "5"', function(){
my_last_string("F#5").should.equal("5");
});
it('maps my_last_string("") to ""', function(){
my_last_string("").should.equal("");
});
});
describe('#string_separated_string2array', function(){
it('maps string_separated_string2array("and", "yes and maybe no and May") to ["yes", "maybe no", "May"]', function(){
string_separated_string2array("and", "yes and maybe no and May").should.eql(["yes", "maybe no", "May"]);
});
it('maps string_separated_string2array("o", "uj k") to ["uj k"]', function(){
string_separated_string2array("o", "uj k").should.eql(["uj k"]);
});
});
// Utility.
describe('#append_ontimes_to_time_signatures', function(){
it('maps append_ontimes_to_time_signatures([{ "barNo": 1, "topNo": 2, "bottomNo": 4 }, { "barNo": 2, "topNo": 3, "bottomNo": 8 }, { "barNo": 4, "topNo": 3, "bottomNo": 4 }, { "barNo": 7, "topNo": 5, "bottomNo": 8 }]) to [{ "barNo": 1, "topNo": 2, "bottomNo": 4, "ontime": 0 }, { "barNo": 2, "topNo": 3, "bottomNo": 8, "ontime": 2 }, { "barNo": 4, "topNo": 3, "bottomNo": 4, "ontime": 5 }, { "barNo": 7, "topNo": 5, "bottomNo": 8, "ontime": 14 }]', function(){
append_ontimes_to_time_signatures([{ "barNo": 1, "topNo": 2, "bottomNo": 4 }, { "barNo": 2, "topNo": 3, "bottomNo": 8 }, { "barNo": 4, "topNo": 3, "bottomNo": 4 }, { "barNo": 7, "topNo": 5, "bottomNo": 8 }]).should.eql([{ "barNo": 1, "topNo": 2, "bottomNo": 4, "ontime": 0 }, { "barNo": 2, "topNo": 3, "bottomNo": 8, "ontime": 2 }, { "barNo": 4, "topNo": 3, "bottomNo": 4, "ontime": 5 }, { "barNo": 7, "topNo": 5, "bottomNo": 8, "ontime": 14 }]);
});
});
describe('#bar_and_beat_number_of_ontime', function(){
it('maps bar_and_beat_number_of_ontime(4, [{ "barNo": 1, "topNo": 2, "bottomNo": 4, "ontime": 0 }, { "barNo": 2, "topNo": 3, "bottomNo": 8, "ontime": 2 }, { "barNo": 4, "topNo": 3, "bottomNo": 4, "ontime": 5 }, { "barNo": 7, "topNo": 5, "bottomNo": 8, "ontime": 14 }]) to [3, 1.5]', function(){
bar_and_beat_number_of_ontime(4, [{ "barNo": 1, "topNo": 2, "bottomNo": 4, "ontime": 0 }, { "barNo": 2, "topNo": 3, "bottomNo": 8, "ontime": 2 }, { "barNo": 4, "topNo": 3, "bottomNo": 4, "ontime": 5 }, { "barNo": 7, "topNo": 5, "bottomNo": 8, "ontime": 14 }]).should.eql([3, 1.5]);
});
});
describe('#clef_sign_and_line2clef_name', function(){
it('maps clef_sign_and_line2clef_name("C", 3) to "alto clef"', function(){
clef_sign_and_line2clef_name("C", 3).should.equal("alto clef");
});
});
describe('#convert_1st_bar2anacrusis_val', function(){
it('maps convert_1st_bar2anacrusis_val({ "$": { "number": "0", "implicit": "yes", "width": "195.58" }, "print": [ { "system-layout": [] } ], "attributes": [ { "divisions": [6], "key": [], "time": [ { "beats": [4], "beat-type": [4] } ], "clef": ["blah"] } ], "note": [ { "rest": [], "duration": [3], "voice": [1], "type": [] }, { "$": [], "pitch": [], "duration": [1], "voice": [2], "type": [], "time-modification": [], "stem": [], "beam": [], "notations": [] }, { "$": [], "pitch": [], "duration": [1], "voice": [2], "type": [], "time-modification": [], "stem": [], "beam": [], "notations": [] }, { "rest": [], "duration": [1], "voice": [2], "type": [], "time-modification": [], "notations": [] } ], "backup": [ { "duration": [3] } ] }, 6) to [-0.5, 4]', function(){
convert_1st_bar2anacrusis_val({ "$": { "number": "0", "implicit": "yes", "width": "195.58" }, "print": [ { "system-layout": [] } ], "attributes": [ { "divisions": [6], "key": [], "time": [ { "beats": [4], "beat-type": [4] } ], "clef": ["blah"] } ], "note": [ { "rest": [], "duration": [3], "voice": [1], "type": [] }, { "$": [], "pitch": [], "duration": [1], "voice": [2], "type": [], "time-modification": [], "stem": [], "beam": [], "notations": [] }, { "$": [], "pitch": [], "duration": [1], "voice": [2], "type": [], "time-modification": [], "stem": [], "beam": [], "notations": [] }, { "rest": [], "duration": [1], "voice": [2], "type": [], "time-modification": [], "notations": [] } ], "backup": [ { "duration": [3] } ] }, 6).should.eql([-0.5, 4]);
});
});
describe('#default_page_and_system_breaks', function(){
it('maps default_page_and_system_breaks([{ "name": "soprn", "id": "P1", "clef": "treble clef", "clefSign": "G", "clefLine": 2, "staffNo": 0 }, { "name": "alto", "id": "P2", "clef": "treble clef", "clefSign": "G", "clefLine": 2, "staffNo": 1 }], 100) to [[21, 41, 61, 81], [5, 9, 13, 17, 25, 29, 33, 37, 45, 49, 53, 57, 65, 69, 73, 77, 85, 89, 93, 97]]', function(){
default_page_and_system_breaks([{ "name": "soprn", "id": "P1", "clef": "treble clef", "clefSign": "G", "clefLine": 2, "staffNo": 0 }, { "name": "alto", "id": "P2", "clef": "treble clef", "clefSign": "G", "clefLine": 2, "staffNo": 1 }], 100).should.eql([[21, 41, 61, 81], [5, 9, 13, 17, 25, 29, 33, 37, 45, 49, 53, 57, 65, 69, 73, 77, 85, 89, 93, 97]]);
});
});
describe('#group_grace_by_contiguous_id', function(){
it('maps group_grace_by_contiguous_id([{ "ID": "28", "pitch": "D4", "MNN": 62, "MPN": 61 }, { "ID": "29", "pitch": "Bb3", "MNN": 58, "MPN": 59 }, { "ID": "15", "pitch": "G3", "MNN": 55, "MPN": 57 }]) to [[{ "ID": "15", "pitch": "G3", "MNN": 55, "MPN": 57 }], [{ "ID": "28", "pitch": "D4", "MNN": 62, "MPN": 61 }, { "ID": "29", "pitch": "Bb3", "MNN": 58, "MPN": 59 }]]', function(){
group_grace_by_contiguous_id([{ "ID": "28", "pitch": "D4", "MNN": 62, "MPN": 61 }, { "ID": "29", "pitch": "Bb3", "MNN": 58, "MPN": 59 }, { "ID": "15", "pitch": "G3", "MNN": 55, "MPN": 57 }]).should.eql([[{ "ID": "15", "pitch": "G3", "MNN": 55, "MPN": 57 }], [{ "ID": "28", "pitch": "D4", "MNN": 62, "MPN": 61 }, { "ID": "29", "pitch": "Bb3", "MNN": 58, "MPN": 59 }]]);
});
});
describe('#guess_morphetic', function(){
it('maps guess_morphetic(54, 4, 5) to 56', function(){
guess_morphetic(54, 4, 5).should.equal(56);
});
it('maps guess_morphetic(67, 5, 5) to 64', function(){
guess_morphetic(67, 5, 5).should.equal(64);
});
});
describe('#guess_morphetic_in_C_major', function(){
it('maps guess_morphetic_in_C_major(66) to 63', function(){
guess_morphetic_in_C_major(66).should.equal(63);
});
it('maps guess_morphetic_in_C_major(56) to 57', function(){
guess_morphetic_in_C_major(56).should.equal(57);
});
});
describe('#midi_note_morphetic_pair2pitch_and_octave', function(){
it('maps midi_note_morphetic_pair2pitch_and_octave(66, 63) to "F#4"', function(){
midi_note_morphetic_pair2pitch_and_octave(66, 63).should.equal("F#4");
});
it('maps midi_note_morphetic_pair2pitch_and_octave(59, 59) to "B3"', function(){
midi_note_morphetic_pair2pitch_and_octave(59, 59).should.equal("B3");
});
});
describe('#MNN2pitch_simple', function(){
it('maps MNN2pitch_simple(66) to "F#4"', function(){
MNN2pitch_simple(66).should.equal("F#4");
});
it('maps MNN2pitch_simple(58) to "A#3"', function(){
MNN2pitch_simple(58).should.equal("A#3");
});
});
describe('#nos_symbols_and_mode2key_name', function(){
it('maps nos_symbols_and_mode2key_name(-3, "minor") to "C minor"', function(){
nos_symbols_and_mode2key_name(-3, "minor").should.equal("C minor");
});
});
describe('#ontime_of_bar_and_beat_number', function(){
it('maps ontime_of_bar_and_beat_number(3, 1.5, [{ "barNo": 1, "topNo": 2, "bottomNo": 4, "ontime": 0 }, { "barNo": 2, "topNo": 3, "bottomNo": 8, "ontime": 2 }, { "barNo": 4, "topNo": 3, "bottomNo": 4, "ontime": 5 }, { "barNo": 7, "topNo": 5, "bottomNo": 8, "ontime": 14 }]) to 4', function(){
ontime_of_bar_and_beat_number(3, 1.5, [{ "barNo": 1, "topNo": 2, "bottomNo": 4, "ontime": 0 }, { "barNo": 2, "topNo": 3, "bottomNo": 8, "ontime": 2 }, { "barNo": 4, "topNo": 3, "bottomNo": 4, "ontime": 5 }, { "barNo": 7, "topNo": 5, "bottomNo": 8, "ontime": 14 }]).should.equal(4);
});
});
describe('#pitch_and_octave2midi_note_morphetic_pair', function(){
it('maps pitch_and_octave2midi_note_morphetic_pair("F#4") to [66, 63]', function(){
pitch_and_octave2midi_note_morphetic_pair("F#4").should.eql([66, 63]);
});
it('maps pitch_and_octave2midi_note_morphetic_pair("B3") to [59, 59]', function(){
pitch_and_octave2midi_note_morphetic_pair("B3").should.eql([59, 59]);
});
});
describe('#remove_duplicate_clef_changes', function(){
it('maps remove_duplicate_clef_changes([{ "barNo": 1, "clef": "treble clef", "staffNo": 0 }, { "barNo": 5, "clef": "alto clef", "staffNo": 0 }, { "barNo": 6, "clef": "alto clef", "staffNo": 0 }, { "barNo": 1, "clef": "bass clef", "staffNo": 1 }, { "barNo": 16, "clef": "bass clef", "staffNo": 1 }]) to [{ "barNo": 1, "clef": "treble clef", "staffNo": 0 }, { "barNo": 6, "clef": "alto clef", "staffNo": 0 }, { "barNo": 1, "clef": "bass clef", "staffNo": 1 }, { "barNo": 16, "clef": "bass clef", "staffNo": 1 }]', function(){
remove_duplicate_clef_changes([{ "barNo": 1, "clef": "treble clef", "staffNo": 0 }, { "barNo": 5, "clef": "alto clef", "staffNo": 0 }, { "barNo": 6, "clef": "alto clef", "staffNo": 0 }, { "barNo": 1, "clef": "bass clef", "staffNo": 1 }, { "barNo": 16, "clef": "bass clef", "staffNo": 1 }]).should.eql([{ "barNo": 1, "clef": "treble clef", "staffNo": 0 }, { "barNo": 6, "clef": "alto clef", "staffNo": 0 }, { "barNo": 1, "clef": "bass clef", "staffNo": 1 }, { "barNo": 16, "clef": "bass clef", "staffNo": 1 }]);
});
});
describe('#resolve_expressions', function(){
it('maps resolve_expressions([{ "ID": "0", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "crescendo" }, "placement": "below", "staffNo": 0 }, { "ID": "1", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "diminuendo" }, "placement": "above", "staffNo": 0 }, { "ID": "2", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "dynamics": "f" }, "placement": "below", "staffNo": 0 }, { "ID": "3", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "stop" }, "placement": "below", "staffNo": 0 }, { "ID": "4", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "stop" }, "placement": "above", "staffNo": 0 }, { "ID": "5", "barOn": 2, "beatOn": 1, "ontime": 3, "type": { "dynamics": "fff" }, "placement": "below", "staffNo": 0 }]) to [{ "ID": "0", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "crescendo" }, "placement": "below", "staffNo": 0, "barOff": 1, "beatOff": 1, "offtime": 0 }, { "ID": "1", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "diminuendo" }, "placement": "above", "staffNo": 0, "barOff": 1, "beatOff": 1, "offtime": 0 }, { "ID": "2", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "dynamics": "f" }, "placement": "below", "staffNo": 0 }, { "ID": "5", "barOn": 1, "beatOn": 2, "ontime": 3, "type": { "dynamics": "fff" }, "placement": "below", "staffNo": 0 }]', function(){
resolve_expressions([{ "ID": "0", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "crescendo" }, "placement": "below", "staffNo": 0 }, { "ID": "1", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "diminuendo" }, "placement": "above", "staffNo": 0 }, { "ID": "2", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "dynamics": "f" }, "placement": "below", "staffNo": 0 }, { "ID": "3", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "stop" }, "placement": "below", "staffNo": 0 }, { "ID": "4", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "stop" }, "placement": "above", "staffNo": 0 }, { "ID": "5", "barOn": 2, "beatOn": 1, "ontime": 3, "type": { "dynamics": "fff" }, "placement": "below", "staffNo": 0 }]).should.eql([{ "ID": "0", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "crescendo" }, "placement": "below", "staffNo": 0, "barOff": 1, "beatOff": 1, "offtime": 0 }, { "ID": "1", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "wedge": "diminuendo" }, "placement": "above", "staffNo": 0, "barOff": 1, "beatOff": 1, "offtime": 0 }, { "ID": "2", "barOn": 1, "beatOn": 1, "ontime": 0, "type": { "dynamics": "f" }, "placement": "below", "staffNo": 0 }, { "ID": "5", "b