mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-28 23:39:36 +00:00
Add median function
This commit is contained in:
parent
d5ce3615cf
commit
9e4d46eecf
2 changed files with 38 additions and 20 deletions
24
arrays.scad
24
arrays.scad
|
@ -1244,6 +1244,30 @@ function group_sort(list, idx) =
|
|||
|
||||
|
||||
|
||||
// Function: list_smallest()
|
||||
// Usage:
|
||||
// small = list_smallest(list, k)
|
||||
// Description:
|
||||
// Returns a set of the k smallest items in list in arbitrary order. The items must be
|
||||
// mutually comparable with native OpenSCAD comparison operations.
|
||||
// Arguments:
|
||||
// list = list to process
|
||||
// k = number of items to return
|
||||
function list_smallest(list, k) =
|
||||
assert(is_list(list))
|
||||
assert(is_finite(k) && k>=0, "k must be nonnegative")
|
||||
let(
|
||||
v = list[rand_int(0,len(list)-1,1)[0]],
|
||||
smaller = [for(li=list) if(li<v) li ],
|
||||
equal = [for(li=list) if(li==v) li ]
|
||||
)
|
||||
len(smaller) == k ? smaller :
|
||||
len(smaller)<k && len(smaller)+len(equal) >= k ? [ each smaller, for(i=[1:k-len(smaller)]) v ] :
|
||||
len(smaller) > k ? list_smallest(smaller, k) :
|
||||
let( bigger = [for(li=list) if(li>v) li ] )
|
||||
concat(smaller, equal, list_smallest(bigger, k-len(smaller) -len(equal)));
|
||||
|
||||
|
||||
// Function: group_data()
|
||||
// Usage:
|
||||
// groupings = group_data(groups, values);
|
||||
|
|
34
math.scad
34
math.scad
|
@ -827,27 +827,21 @@ function mean(v) =
|
|||
sum(v)/len(v);
|
||||
|
||||
|
||||
// Function: ninther()
|
||||
// Usage:
|
||||
// med = ninther(v)
|
||||
// Description:
|
||||
// Finds a value in the input list of numbers `v` that is the median of a
|
||||
// sample of 9 entries of `v`.
|
||||
// It is a much faster approximation of the true median computation.
|
||||
// Arguments:
|
||||
// v = an array of numbers
|
||||
function ninther(v) =
|
||||
let( l=len(v) )
|
||||
l<=4 ? l<=2 ? v[0] : _med3(v[0], v[1], v[2]) :
|
||||
l==5 ? _med3(v[0], _med3(v[1], v[2], v[3]), v[4]) :
|
||||
_med3(_med3(v[0],v[floor(l/6)],v[floor(l/3)]),
|
||||
_med3(v[floor(l/3)],v[floor(l/2)],v[floor(2*l/3)]),
|
||||
_med3(v[floor(2*l/3)],v[floor((5*l/3 -1)/2)],v[l-1]) );
|
||||
|
||||
// the median of a triple
|
||||
function _med3(a,b,c) =
|
||||
a < c ? a < b ? min(b,c) : min(a,c) :
|
||||
b < c ? min(a,c) : min(a,b);
|
||||
// Function: median()
|
||||
// Usage:
|
||||
// middle = median(v)
|
||||
// Description:
|
||||
// Returns the median of the given vector.
|
||||
function median(v) =
|
||||
assert(is_vector(v), "Input to median must be a vector")
|
||||
len(v)%2 ? max( list_smallest(v, ceil(len(v)/2)) ) :
|
||||
let( lowest = list_smallest(v, len(v)/2 + 1),
|
||||
max = max(lowest),
|
||||
imax = search(max,lowest,1),
|
||||
max2 = max([for(i=idx(lowest)) if(i!=imax[0]) lowest[i] ])
|
||||
)
|
||||
(max+max2)/2;
|
||||
|
||||
|
||||
// Function: convolve()
|
||||
|
|
Loading…
Reference in a new issue