From f598426344099b13f89e78716ee1be27616a14f6 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Fri, 23 Oct 2020 19:06:30 -0400 Subject: [PATCH] Add cumprod function and regression test --- math.scad | 38 ++++++++++++++++++++++++++++++++++++++ tests/test_math.scad | 22 ++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/math.scad b/math.scad index c0ac6ab..6cb1362 100644 --- a/math.scad +++ b/math.scad @@ -617,6 +617,44 @@ function _product(v, i=0, _tot) = +// Function: cumprod() +// Description: +// Returns a list where each item is the cumulative product of all items up to and including the corresponding entry in the input list. +// If passed an array of vectors, returns a list of elementwise vector products. If passed a list of square matrices returns matrix +// products multiplying in the order items appear in the list. +// Arguments: +// list = The list to get the product of. +// Example: +// cumprod([1,3,5]); // returns [1,3,15] +// cumprod([2,2,2]); // returns [2,4,8] +// cumprod([[1,2,3], [3,4,5], [5,6,7]])); // returns [[1, 2, 3], [3, 8, 15], [15, 48, 105]] +function cumprod(list) = + is_vector(list) ? _cumprod(list) : + assert(is_consistent(list), "Input must be a consistent list of scalars, vectors or square matrices") + is_matrix(list[0]) ? assert(len(list[0])==len(list[0][0]), "Matrices must be square") _cumprod(list) + : _cumprod_vec(list); + +function _cumprod(v,_i=0,_acc=[]) = + _i==len(v) ? _acc : + _cumprod( + v, _i+1, + concat( + _acc, + [_i==0 ? v[_i] : _acc[len(_acc)-1]*v[_i]] + ) + ); + +function _cumprod_vec(v,_i=0,_acc=[]) = + _i==len(v) ? _acc : + _cumprod_vec( + v, _i+1, + concat( + _acc, + [_i==0 ? v[_i] : vmul(_acc[len(_acc)-1],v[_i])] + ) + ); + + // Function: outer_product() // Usage: // x = outer_product(u,v); diff --git a/tests/test_math.scad b/tests/test_math.scad index 824098a..1d9fee9 100644 --- a/tests/test_math.scad +++ b/tests/test_math.scad @@ -836,6 +836,28 @@ module test_linear_solve(){ test_linear_solve(); +module test_cumprod(){ + assert_equal(cumprod([1,2,3,4]), [1,2,6,24]); + assert_equal(cumprod([4]), [4]); + assert_equal(cumprod([]),[]); + assert_equal(cumprod([[2,3],[4,5],[6,7]]), [[2,3],[8,15],[48,105]]); + assert_equal(cumprod([[5,6,7]]),[[5,6,7]]); + assert_equal(cumprod([ + [[1,2],[3,4]], + [[-4,5],[6,4]], + [[9,-3],[4,3]] + ]), + [ + [[1,2],[3,4]], + [[8,13],[12,31]], + [[124,15],[232,57]] + ]); + assert_equal(cumprod([[[1,2],[3,4]]]), [[[1,2],[3,4]]]); +} +test_cumprod(); + + + module test_outer_product(){ assert_equal(outer_product([1,2,3],[4,5,6]), [[4,5,6],[8,10,12],[12,15,18]]); assert_equal(outer_product([1,2],[4,5,6]), [[4,5,6],[8,10,12]]);