Mercurial > hg > may
changeset 434:6920a0f107a6
Short-circuit some identity transformations
author | Chris Cannam |
---|---|
date | Tue, 08 Oct 2013 08:18:22 +0100 |
parents | 5d7ad9494633 |
children | bdda1da38eb1 |
files | src/may/vector.yeti |
diffstat | 1 files changed, 41 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/src/may/vector.yeti Tue Oct 08 08:18:11 2013 +0100 +++ b/src/may/vector.yeti Tue Oct 08 08:18:22 2013 +0100 @@ -7,6 +7,10 @@ * list<number>, a vector can be faster and more compact when dealing * with dense data of suitable range and precision such as sampled * sequences. + * + * Because vectors are immutable, functions that transform them will + * return the original data for identity transformations + * (e.g. resizing to the vector's existing length). */ module may.vector; @@ -87,28 +91,34 @@ copyOf v is ~double[] -> ~double[] = Arrays#copyOf(v, list' v |> length); +/// Return the given vector as a primitive array. Modifying the +/// array contents will not affect the original vector. +primitive = copyOf; + /// Return a new vector containing a subset of the elements of the -/// given vector, from index start (inclusive) to index end +/// given vector, from index start (inclusive) to index finish /// (exclusive). (The function name and argument order are chosen for /// symmetry with the standard library slice and strSlice functions.) -slice v start end is ~double[] -> number -> number -> ~double[] = - if start < 0 then slice v 0 end - elif start > length' v then slice v (length' v) end +slice v start finish is ~double[] -> number -> number -> ~double[] = + (len = length' v; + if start == 0 and finish == len then v + elif start < 0 then slice v 0 finish + elif start > len then slice v len finish + elif finish < start then slice v start start + elif finish > len then slice v start len else - if end < start then slice v start start - elif end > length' v then slice v start (length' v) - else - Arrays#copyOfRange(v, start, end); - fi + Arrays#copyOfRange(v, start, finish); + fi); + +/// Return a vector of length n, containing the contents of the given +/// vector v. If v is longer than n, the contents will be truncated; +/// if shorter, they will be padded with zeros. +resizedTo n v is number -> ~double[] -> ~double[] = + if n == length' v then v; + else Arrays#copyOf(v, n); fi; -/// Return a new vector of length n, containing the contents of the -/// given vector v. If v is longer than n, the contents will be -/// truncated; if shorter, they will be padded with zeros. -resizedTo n v is number -> ~double[] -> ~double[] = - Arrays#copyOf(v, n); - -/// Return a new vector that is the reverse of the given vector. Name +/// Return a vector that is the reverse of the given vector. Name /// chosen (in preference to passive "reversed") for symmetry with the /// standard library list reverse function. reverse v is ~double[] -> ~double[] = @@ -123,19 +133,20 @@ /// given vectors, in order. (Unlike the standard module list concat /// function, this one cannot be lazy.) concat vv is list?<~double[]> -> ~double[] = - if empty? vv then zeros 0 - else - len = sum (map length' vv); - v0 = head vv; - vout = Arrays#copyOf(v0, len); - var base = length' v0; - for (tail vv) do v: - vlen = length' v; - System#arraycopy(v, 0, vout, base, vlen); - base := base + vlen; - done; - vout; - fi; + case vv of + [v]: v; + v0::rest: + (len = sum (map length' vv); + vout = Arrays#copyOf(v0 is ~double[], len); + var base = length' v0; + for rest do v: + vlen = length' v; + System#arraycopy(v, 0, vout, base, vlen); + base := base + vlen; + done; + vout); + _: zeros 0; + esac; /// Return a single new vector that contains the contents of the given /// vector, repeated n times. The vector will therefore have length n @@ -148,7 +159,7 @@ consts, ones, vector v = v, - primitive = copyOf, + primitive, floats, fromFloats, fromList,