UNPKG

maia-util

Version:

Utility math and music functions supporting various applications by Music Artificial Intelligence Algorithms, Inc.

978 lines (778 loc) 67 kB
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