@@ -41,29 +41,37 @@ function findtruncated(values::AbstractVector, strategy::TruncationByOrder)
4141 return partialsortperm (values, 1 : howmany; strategy. by, strategy. rev)
4242end
4343function findtruncated_sorted (values:: AbstractVector , strategy:: TruncationByOrder )
44- howmany = min (strategy. howmany, length (values))
45- return strategy. rev ? (1 : howmany) : ((length (values) - howmany + 1 ): length (values))
44+ @assert strategy. by === abs
45+ if strategy. by === abs
46+ howmany = min (strategy. howmany, length (values))
47+ return strategy. rev ? (1 : howmany) : ((length (values) - howmany + 1 ): length (values))
48+ else
49+ return findtruncated (values, strategy)
50+ end
4651end
4752
4853function findtruncated (values:: AbstractVector , strategy:: TruncationByFilter )
49- ind = findall (strategy. filter, values)
50- return ind
54+ # pre-allocate bitvector to enforce the filter function returns a Bool
55+ mask = similar (BitArray, eachindex (values))
56+ mask .= strategy. filter .(values)
57+ return mask
5158end
5259
5360function findtruncated (values:: AbstractVector , strategy:: TruncationByValue )
5461 atol = max (strategy. atol, strategy. rtol * norm (values, strategy. p))
55- filter = (strategy. rev ? ≤ (atol) : ≥ (atol)) ∘ strategy. by
56- return findall (filter, values )
62+ filter = (strategy. keep_below ? ≤ (atol) : ≥ (atol)) ∘ strategy. by
63+ return findtruncated (values, truncfilter (filter) )
5764end
58- function findtruncated_sorted (values:: AbstractVector , strategy:: TruncationByValue )
65+ function findtruncated_svd (values:: AbstractVector , strategy:: TruncationByValue )
66+ strategy. by === abs || return findtruncated (values, strategy)
67+
5968 atol = max (strategy. atol, strategy. rtol * norm (values, strategy. p))
60- @assert strategy. by === abs || strategy. by === real " sorting strategy incompatible with implementation"
61- if strategy. rev
62- i = searchsortedfirst (values, atol; by= strategy. by, rev= true )
63- return i: length (values)
64- else
65- i = searchsortedlast (values, atol; by= strategy. by, rev= true )
69+ if strategy. keep_above
70+ i = searchsortedlast (values, atol; by= abs, rev= true )
6671 return 1 : i
72+ else
73+ i = searchsortedfirst (values, atol; by= abs, rev= true )
74+ return i: length (values)
6775 end
6876end
6977
@@ -97,10 +105,20 @@ function _truncerr_impl(values::AbstractVector, I; atol::Real=0, rtol::Real=0, p
97105end
98106
99107function findtruncated (values:: AbstractVector , strategy:: TruncationIntersection )
100- inds = map (Base. Fix1 (findtruncated, values), strategy. components)
101- return intersect (inds ... )
108+ return mapreduce (Base. Fix1 (findtruncated, values), _ind_intersect, strategy. components;
109+ init = trues ( length (values)) )
102110end
103111function findtruncated_sorted (values:: AbstractVector , strategy:: TruncationIntersection )
104- inds = map (Base. Fix1 (findtruncated_sorted, values), strategy . components)
105- return intersect (inds ... )
112+ return mapreduce (Base. Fix1 (findtruncated_sorted, values), _ind_intersect,
113+ strategy . components; init = trues ( length (values)) )
106114end
115+
116+ # when one of the ind selections is a bitvector, have to handle differently
117+ function _ind_intersect (A:: AbstractVector{Bool} , B:: AbstractVector )
118+ result = falses (length (A))
119+ result[B] .= @view A[B]
120+ return result
121+ end
122+ _ind_intersect (A:: AbstractVector , B:: AbstractVector{Bool} ) = _ind_intersect (B, A)
123+ _ind_intersect (A:: AbstractVector{Bool} , B:: AbstractVector{Bool} ) = A .& B
124+ _ind_intersect (A, B) = intersect (A, B)
0 commit comments