function ArrayMax(array){ //{{{ //Calculate array max using for loop instead of Math.max.apply(null, array) to avoid recursive stack overflow in mobile browsers var max=-Infinity; for (var i=0;i JSON.stringify(a) === JSON.stringify(b); let uniques = []; let indexA = []; let indexC = []; let itemsFound = {};; for(let i = 0, l = arr.length; i < l; i++) { let stringified = JSON.stringify(arr[i]); if (typeof(itemsFound[stringified]) != 'undefined') { indexC.push(itemsFound[stringified]); continue; } uniques.push(arr[i]); indexA.push(i); itemsFound[stringified] = uniques.length-1; indexC.push(itemsFound[stringified]); } //assert arr == uniques[indexC,:]; for (let i = 0; i < indexC.length; i++) { if (!equals(arr[i], uniques[indexC[i]])) { throw new Error('bad implementation'); } } //assert uniques == arr[indexA, :]; for (let i = 0; i < indexA.length; i++) { if (!equals(uniques[i], arr[indexA[i]])) { throw new Error('bad implementation'); } } let [uniquesSorted, indexInToOut, indexOutToIn] = ArraySortWithIndices(uniques); //indexMapping is the index of the edge in the old array indexCSorted = []; //indexC.length == arr.length //assert uniquesSorted[i,:] = uniques[indexInToOut[i],:] for (let i = 0; i < indexInToOut.length; i++) { if (!equals(uniquesSorted[i], uniques[indexInToOut[i]])) { console.log(i, uniquesSorted[indexInToOut[i]], uniques[i]); throw new Error('bad implementation'); } } //assert uniques[i,:] = uniquesSorted[indexOutToIn[i],:] for (let i = 0; i < indexOutToIn.length; i++) { if (!equals(uniques[i], uniquesSorted[indexOutToIn[i]])) { console.log(i, uniques[indexOutToIn[i]], uniquesSorted[i]); throw new Error('bad implementation'); } } //GOAL: assert arr[i,:] == uniquesSorted[indexCSorted[i], :] //GIVEN: assert arr[i,:] == uniques[indexC[i],:]; //GIVEN: assert uniquesSorted[i,:] = uniques[indexInToOut[i],:] //GIVEN: assert uniques[i,:] = uniquesSorted[indexOutToIn[i],:] //assert uniques[indexC[i],:] == uniquesSorted[indexOutToIn[indexC[i]],:] //assert uniquesSorted[indexCSorted[i],:]; == uniquesSorted[indexOutToIn[indexC[i]],:]; for (let i = 0; i < arr.length; i++) { indexCSorted[i] = indexOutToIn[indexC[i]]; } for (let i = 0; i < indexC.length; i++) { if (!equals(arr[i], uniquesSorted[indexCSorted[i]])) { console.log(i, arr[i], uniquesSorted[indexCSorted[i]]); throw new Error('bad implementation'); } } indexASorted = []; //indexA.length == uniques.length //GOAL: uniquesSorted[i, :] == arr[indexASorted[i], :] //GIVEN: assert arr[i,:] == uniques[indexC[i],:]; //GIVEN: assert arr[indexA[i],:] == uniques[i,:]; //GIVEN: assert uniques[indexInToOut[i],:] == uniquesSorted[i,:] //GIVEN: assert uniques[i,:] = uniquesSorted[indexOutToIn[i],:] //assert uniquesSorted[i,:] == uniques[indexInToOut[i],:] //assert uniques[indexInToOut[i],:] == arr[indexA[indexInToOut[i]],:]; //assert indexA[indexInToOut] == indexASorted //indexASorted == indexA[indexMapping[i]] for (let i = 0; i < indexA.length; i++) { indexASorted[i] = indexA[indexInToOut[i]]; } //assert uniques == arr[indexA, :]; for (let i = 0; i < indexASorted.length; i++) { if (!equals(uniquesSorted[i], arr[indexASorted[i]])) { throw new Error('bad implementation'); } } console.log('Good uniques'); return [uniquesSorted, indexASorted, indexCSorted]; } else { throw new Error('ArrayUnique non "rows" not supported'); } } else { return arr.reverse().filter(function (e, i, arr) { return arr.indexOf(e, i+1) === -1; }).reverse(); } } //}}} function ArraySortWithIndices(toSort, sortingFunction) { //{{{ //returns the sorted and index such that toSort[index[i]] == sorted[i] let toSortCopy = []; for (var i = 0; i < toSort.length; i++) { toSortCopy[i] = [toSort[i], i]; } if (typeof(sortingFunction) == 'undefined') { let numeric2DFunction = function(a, b) { if (a[0][0] == b[0][0]) { return a[0][1] - b[0][1]; } else { return a[0][0] - b[0][0]; } }; sortingFunction = numeric2DFunction; } toSortCopy.sort(sortingFunction); let indicesInToOut = []; let indicesOutToIn = []; let sorted = []; for (var j = 0; j < toSortCopy.length; j++) { indicesInToOut[j] = toSortCopy[j][1]; indicesOutToIn[toSortCopy[j][1]] = j; sorted[j] = toSortCopy[j][0]; } return [sorted, indicesInToOut, indicesOutToIn]; } //}}} function ArraySort(array,dim) { //{{{ let numericFunction = function(a, b) { return a - b; }; let numeric2DFunction = function(a, b) { return a[0] - b[0]; }; if (arguments.length == 2){ if (dim == 1) { array.sort(numeric2DFunction); } else if (dim == 2) { for (let i = 0; i < array.length; i++) { array[i].sort(numericFunction); } } else { throw new Error('ArraySort dim > 2 not yet supported') } return array; } else { return array.sort(numericFunction); } } //}}} function ArrayRange(lower, upper) { //{{{ var range = upper - lower + 1; return Array.apply(null, Array(range)).map(function (val, ind) {return ind + lower;}); } //}}} function ArrayAny(array) { //{{{ //Emulates Matlab 'any' function for(var i=0;i=value)return 1; } return 0; } //}}} function ArrayAnyAboveStrict(array,value) { //{{{ for(var i=0;ivalue)return 1; } return 0; } //}}} function ArrayAnd(array1,array2) { //{{{ var array = new Array(array1.length); for (var i=0;i array2; } } else { for(var i=0;i array2[i]; } } return array; } //}}} function ArrayLessEqualThan(array1,array2) { //{{{ var array = new Array(array1.length); if (typeof(array2) == 'number') { for(var i=0;i= array2; } } else { for(var i=0;i= array2[i]; } } return array; } //}}} function ArrayIsMember(array1,array2) { //{{{ var array=NewArrayFill(array1.length,0); for (var i=0;i