Sort debugging and optimizing

There were bugs in the previous sorting functions. They didn't check the homogeneity of the input list before calling _sort_scalars and _sort_vectors. The bug might result in wrong order and missing list elements in the output.
Besides correcting the bug a recode of all sorting functions result in better performance and a enlargement of their scope. With the new functions, list of vectors of any dimension may be sorted, even with idx given, with the native comparison operators. The scope of indexed sorting is also extended.

The file test_arrays has been extended to check the new funcionality.

New functions:

is_homogeneous - checks if a list has elements of the same type (although not distinguing booleans from numbers) up to a given depth
_sort_vectors - internal function to sort homgeneous lists of vectors using native comparison operators; extends the scope of the previous _sort_vectors# functions with better performance
_lexical_sort - internal function to sort non-homogeneous lists; uses compare_vals
_indexed_sort - internal function to perform indexed sorting of non-homogeneous lists; uses compar_vals

Changed/reviewed functions:
_valid_idx - doesn't requires the input of imin and imax args
sort - explores the internal functions to get better performance and an enlarged scope
sortidx - explores the internal functions to get better performance and an enlarged scope
_sort_general - just for sortings of non-homogeneous lists using compare_vals
_array_dim_recurse - changed for bit better performance

Functions eliminated:
 _sort_vectors1
 _sort_vectors2
 _sort_vectors3
 _sort_vectors4
This commit is contained in:
RonaldoCMP
2020-08-30 12:12:36 +01:00
parent 14b0f264ac
commit bbe4ad1467
2 changed files with 198 additions and 164 deletions

View File

@@ -3,6 +3,16 @@ include <../std.scad>
// Section: List Query Operations
module test_is_homogeneous(){
assert(is_homogeneous([[1,["a"]], [2,["b"]]])==true);
assert(is_homogeneous([[1,["a"]], [2,[true]]])==false);
assert(is_homogeneous([[1,["a"]], [2,[true]]],1)==true);
assert(is_homogeneous([[1,["a"]], [2,[true]]],2)==false);
assert(is_homogeneous([[1,["a"]], [true,["b"]]])==true);
}
test_is_homogeneous();
module test_select() {
l = [3,4,5,6,7,8,9];
assert(select(l, 5, 6) == [8,9]);
@@ -46,7 +56,6 @@ test_in_list();
module test_min_index() {
assert(min_index([5,3,9,6,2,7,8,2,1])==8);
assert(min_index([5,3,9,6,2,7,8,2,7],all=true)==[4,7]);
// assert(min_index([],all=true)==[]);
}
test_min_index();
@@ -54,7 +63,6 @@ test_min_index();
module test_max_index() {
assert(max_index([5,3,9,6,2,7,8,9,1])==2);
assert(max_index([5,3,9,6,2,7,8,9,7],all=true)==[2,7]);
// assert(max_index([],all=true)==[]);
}
test_max_index();
@@ -74,6 +82,7 @@ module test_list_decreasing() {
}
test_list_decreasing();
// Section: Basic List Generation
module test_repeat() {
@@ -155,7 +164,6 @@ module test_list_remove() {
}
test_list_remove();
module test_list_remove_values() {
animals = ["bat", "cat", "rat", "dog", "bat", "rat"];
assert(list_remove_values(animals, "rat") == ["bat","cat","dog","bat","rat"]);
@@ -258,15 +266,24 @@ test_shuffle();
module test_sort() {
assert(sort([7,3,9,4,3,1,8]) == [1,3,3,4,7,8,9]);
assert(sort(["cat", "oat", "sat", "bat", "vat", "rat", "pat", "mat", "fat", "hat", "eat"]) == ["bat", "cat", "eat", "fat", "hat", "mat", "oat", "pat", "rat", "sat", "vat"]);
assert(sort([[4,0],[7],[3,9],20,[4],[3,1],[8]]) == [20,[3,1],[3,9],[4],[4,0],[7],[8]]);
assert(sort([[4,0],[7],[3,9],20,[4],[3,1],[8]],idx=1) == [[7],20,[4],[8],[4,0],[3,1],[3,9]]);
assert(sort([[8,6],[3,1],[9,2],[4,3],[3,4],[1,5],[8,0]]) == [[1,5],[3,1],[3,4],[4,3],[8,0],[8,6],[9,2]]);
assert(sort([[8,0],[3,1],[9,2],[4,3],[3,4],[1,5],[8,6]],idx=1) == [[8,0],[3,1],[9,2],[4,3],[3,4],[1,5],[8,6]]);
assert(sort(["cat", "oat", "sat", "bat", "vat", "rat", "pat", "mat", "fat", "hat", "eat"])
== ["bat", "cat", "eat", "fat", "hat", "mat", "oat", "pat", "rat", "sat", "vat"]);
assert(sort(enumerate([[2,3,4],[1,2,3],[2,4,3]]),idx=1)==[[1,[1,2,3]], [0,[2,3,4]], [2,[2,4,3]]]);
assert(sort([0,"1",[1,0],2,"a",[1]])== [0,2,"1","a",[1],[1,0]]);
assert(sort([["oat",0], ["cat",1], ["bat",3], ["bat",2], ["fat",3]])== [["bat",2],["bat",3],["cat",1],["fat",3],["oat",0]]);
}
test_sort();
module test_sortidx() {
lst1 = ["d","b","e","c"];
lst1 = ["da","bax","eaw","cav"];
assert(sortidx(lst1) == [1,3,0,2]);
lst5 = [3,5,1,7];
assert(sortidx(lst5) == [2,0,1,3]);
lst2 = [
["foo", 88, [0,0,1], false],
["bar", 90, [0,1,0], true],
@@ -276,11 +293,22 @@ module test_sortidx() {
assert(sortidx(lst2, idx=1) == [3,0,2,1]);
assert(sortidx(lst2, idx=0) == [1,2,0,3]);
assert(sortidx(lst2, idx=[1,3]) == [3,0,2,1]);
lst3 = [[-4, 0, 0], [0, 0, -4], [0, -4, 0], [-4, 0, 0], [0, -4, 0], [0, 0, 4], [0, 0, -4], [0, 4, 0], [4, 0, 0], [0, 0, 4], [0, 4, 0], [4, 0, 0]];
lst3 = [[-4,0,0],[0,0,-4],[0,-4,0],[-4,0,0],[0,-4,0],[0,0,4],
[0,0,-4],[0,4,0],[4,0,0],[0,0,4],[0,4,0],[4,0,0]];
assert(sortidx(lst3)==[0,3,2,4,1,6,5,9,7,10,8,11]);
assert(sortidx([[4,0],[7],[3,9],20,[4],[3,1],[8]]) == [3,5,2,4,0,1,6]);
assert(sortidx([[4,0],[7],[3,9],20,[4],[3,1],[8]],idx=1) == [1,3,4,6,0,5,2]);
lst4=[0,"1",[1,0],2,"a",[1]];
assert(sortidx(lst4)== [0,3,1,4,5,2]);
assert(sortidx(["cat","oat","sat","bat","vat","rat","pat","mat","fat","hat","eat"])
== [3,0,10,8,9,7,1,6,5,2,4]);
assert(sortidx([["oat",0], ["cat",1], ["bat",3], ["bat",2], ["fat",3]])== [3,2,1,4,0]);
assert(sortidx(["Belfry", "OpenScad", "Library", "Documentation"])==[0,3,2,1]);
assert(sortidx(["x",1,[],0,"abc",true])==[5,3,1,4,0,2]);
}
test_sortidx();
module test_unique() {
assert(unique([]) == []);
assert(unique([8]) == [8]);
@@ -336,10 +364,8 @@ module test_set_intersection() {
test_set_intersection();
// Arrays
module test_add_scalar() {
assert(add_scalar([1,2,3],3) == [4,5,6]);
assert(add_scalar([[1,2,3],[3,4,5]],3) == [[4,5,6],[6,7,8]]);
@@ -473,6 +499,12 @@ module test_array_dim() {
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 0) == 2);
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 2) == 3);
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9]]]) == [2,undef,3]);
assert(array_dim([1,2,3,4,5,6,7,8,9]) == [9]);
assert(array_dim([[1],[2],[3],[4],[5],[6],[7],[8],[9]]) == [9,1]);
assert(array_dim([]) == [0]);
assert(array_dim([[]]) == [1,0]);
assert(array_dim([[],[]]) == [2,0]);
assert(array_dim([[],[1]]) == [2,undef]);
}
test_array_dim();
@@ -486,7 +518,4 @@ module test_transpose() {
test_transpose();
cube();
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap