Class: CASlabIterator

Inherits:
CAIterator show all
Defined in:
lib/carray/slab_iterator.rb

Overview

CASlabIterator.

Created by the C indexer dispatch when an index uses the :> slab-axis sigil (e.g. ca[nil, :>, :>]). It is a thin sugar over each_slab / map_slab / reduce_slab: :> axes become the slab handed to the block; the remaining (sliced) axes are the outer iteration space.

ca[nil, :>].each { |row| ... } # = ca.each_slab(axis: 1) ca[2..5, :>, :>].map { |slab| ... } # = ca[2..5,nil,nil].map_slab(axis: [-2,-1])

Surface is intentionally minimal (each / map / reduce); to_a / count / size and other Enumerable extras are deferred.

Naming note: distinct from the C-defined CArray::SlabIterator engine in ext/carray_slab.c -- this is the Ruby-level sigil iterator that delegates to each_slab / map_slab / reduce_slab. Loaded lazily via autoload from lib/carray/autoload/autoload_base.rb on first ca[..., :>] evaluation.

Instance Attribute Summary collapse

Attributes inherited from CAIterator

#ndim, #shape

Instance Method Summary collapse

Constructor Details

#initialize(reference, slab_axes) ⇒ CASlabIterator

Built from C via CASlabIterator.new(reference, slab_axes): reference is the sliced base view (with :> axes as full range), slab_axes are the positions marked with :>.



24
25
26
27
28
29
30
31
32
# File 'lib/carray/slab_iterator.rb', line 24

def initialize (reference, slab_axes)
  @reference = reference
  @slab_axes = slab_axes
  rdim = reference.shape
  @outer_positions = (0...reference.ndim).reject { |k| slab_axes.include?(k) }.freeze
  @shape             = @outer_positions.map { |k| rdim[k] }
  @ndim            = @shape.size
  self
end

Instance Attribute Details

#referenceObject (readonly)

The array being iterated (slab exposes it as reference; block / window iterators expose theirs as source). The base has no common accessor.



36
37
38
# File 'lib/carray/slab_iterator.rb', line 36

def reference
  @reference
end

#slab_axesObject (readonly)

The array being iterated (slab exposes it as reference; block / window iterators expose theirs as source). The base has no common accessor.



36
37
38
# File 'lib/carray/slab_iterator.rb', line 36

def slab_axes
  @slab_axes
end

Instance Method Details

#count(v = <none>) ⇒ CArray

Per-slab count, delegating to reference.count(..., axis: slab_axes). No argument counts present (non-masked) cells; count(UNDEF) counts masked cells; count(v) counts cells equal to v.

Returns:

  • (CArray)

    one count per slab



116
117
118
119
120
121
# File 'lib/carray/slab_iterator.rb', line 116

def count (*args)
  return count_not_masked if args.empty?
  # CABlock / CAWindow shadow #count with a geometry accessor, and @reference
  # may be such a view, so dispatch CArray#count explicitly for count(v).
  CArray.instance_method(:count).bind_call(@reference, *args, axis: @slab_axes)
end

#count_maskedCArray

Per-slab count of masked cells.

Returns:



133
134
135
# File 'lib/carray/slab_iterator.rb', line 133

def count_masked
  @reference.count_masked(axis: @slab_axes)
end

#count_not_maskedCArray

Per-slab count of present (non-masked) cells.

Returns:



126
127
128
# File 'lib/carray/slab_iterator.rb', line 126

def count_not_masked
  @reference.count_not_masked(axis: @slab_axes)
end

#each({ |slab| ... }) {|slab| ... } ⇒ Enumerator, self

Yields each slab as an inner CArray. Without a block, returns an Enumerator from each_slab.

Yield Parameters:

Returns:

  • (Enumerator, self)


52
53
54
55
# File 'lib/carray/slab_iterator.rb', line 52

def each (&block)
  return @reference.each_slab(axis: @slab_axes) unless block
  @reference.each_slab(axis: @slab_axes, &block)
end

#elementsCArray

Per-slab cell count (structural, mask-independent). Every slab has the same shape, so this is a constant array shaped like the outer iteration space.

Returns:



142
143
144
145
146
147
148
149
# File 'lib/carray/slab_iterator.rb', line 142

def elements
  sz  = @slab_axes.inject(1) { |p, ax| p * @reference.shape[ax] }
  # count_not_masked gives the correct output shape (and, unlike bare #count,
  # is not shadowed by CABlock / CAWindow); overwrite with the constant size.
  out = @reference.count_not_masked(axis: @slab_axes)
  out[] = sz
  out
end

#kernel_at_index(idx) ⇒ Object

Slab view at outer index idx (Array, length = self.ndim). Returns @reference[*full_idx] where slab axes are nil (full range) and outer axes take their values from idx.



41
42
43
44
45
# File 'lib/carray/slab_iterator.rb', line 41

def kernel_at_index (idx)
  full = Array.new(@reference.ndim)        # nil at every position
  @outer_positions.each_with_index { |k, i| full[k] = idx[i] }
  @reference[*full]
end

#map({ |slab| ... }) {|slab| ... } ⇒ CArray

Returns a new CArray built by applying the block to each slab, delegating to map_slab.

Yield Parameters:

Yield Returns:

  • (Object)

    per-slab result.

Returns:



63
64
65
# File 'lib/carray/slab_iterator.rb', line 63

def map (&block)
  @reference.map_slab(axis: @slab_axes, &block)
end

#medianCArray

Per-slab median.

Returns:



162
163
164
165
166
167
168
# File 'lib/carray/slab_iterator.rb', line 162

def median
  if @slab_axes.size == 1
    @reference.median(axis: @slab_axes[0])
  else
    @reference.reduce_slab(axis: @slab_axes) { |s| s.median }
  end
end

#cumsumCArray #cumprodCArray #cummaxCArray #cumminCArray #cumcountCArray

Overloads:

  • #cumsumCArray

    Per-slab inclusive running sum (float64), reference-shaped.

    Returns:

  • #cumprodCArray

    Per-slab inclusive running product (float64), reference-shaped.

    Returns:

  • #cummaxCArray

    Per-slab inclusive running maximum (reference dtype), reference-shaped.

    Returns:

  • #cumminCArray

    Per-slab inclusive running minimum (reference dtype), reference-shaped.

    Returns:

  • #cumcountCArray

    Per-slab running count of present cells (int64), reference-shaped.

    Returns:



105
106
107
108
109
# File 'lib/carray/slab_iterator.rb', line 105

[:sum, :prod, :mean, :min, :max, :variance, :stddev, :all, :any,
 :variancep, :stddevp, :minmax, :min_index, :max_index,
 :min_addr, :max_addr].each do |op|
  define_method(op) { @reference.send(op, axis: @slab_axes) }
end

#percentile(*pers) ⇒ CArray+

Per-slab percentile(s). One argument returns one CArray; several return an array of CArrays (as CArray#percentile).

Returns:



174
175
176
177
178
179
180
181
# File 'lib/carray/slab_iterator.rb', line 174

def percentile (*pers)
  if @slab_axes.size == 1
    @reference.percentile(*pers, axis: @slab_axes[0])
  else
    rs = pers.map { |p| @reference.reduce_slab(axis: @slab_axes) { |s| s.percentile(p) } }
    pers.size == 1 ? rs[0] : rs
  end
end

#quantileArray<CArray>

Per-slab five-number summary [min, Q1, median, Q3, max] (five CArrays), as CArray#quantile.

Returns:



187
188
189
190
191
192
193
194
195
# File 'lib/carray/slab_iterator.rb', line 187

def quantile
  if @slab_axes.size == 1
    @reference.quantile(axis: @slab_axes[0])
  else
    [0, 25, 50, 75, 100].map { |p|
      @reference.reduce_slab(axis: @slab_axes) { |s| s.percentile(p) }
    }
  end
end

#reduce({ |acc, slab| ... }) {|acc, slab| ... } ⇒ Object #reduce(init) {|acc, slab| ... } ⇒ Object

Overloads:

  • #reduce({ |acc, slab| ... }) {|acc, slab| ... } ⇒ Object

    Reduces the slabs with reduce_slab. The block-only form uses the first slab as the seed; the init form starts from init.

    Yield Parameters:

    • acc (Object)

      running accumulator.

    • slab (CArray)

      next slab.

    Yield Returns:

    • (Object)

      updated accumulator.

    Returns:

    • (Object)
  • #reduce(init) {|acc, slab| ... } ⇒ Object

    Parameters:

    • init (Object)

      initial accumulator value.

    Yield Parameters:

    Yield Returns:

    • (Object)

    Returns:

    • (Object)


80
81
82
83
84
85
86
# File 'lib/carray/slab_iterator.rb', line 80

def reduce (*args, &block)
  if args.empty?
    @reference.reduce_slab(axis: @slab_axes, &block)
  else
    @reference.reduce_slab(axis: @slab_axes, init: args[0], &block)
  end
end

#sort_addrCArray

Per-slab sort by flat source address. Delegates to reference.sort_addr(axis: slab_axis): reference-shaped, each slab's cells carry the flat source addresses that sort that slab ascending.

Returns:

  • (CArray)

    reference-shaped int64



209
210
211
# File 'lib/carray/slab_iterator.rb', line 209

def sort_addr
  @reference.sort_addr(axis: single_sort_axis(:sort_addr))
end

#sort_indexCArray

Per-slab sort by axis-local index (usable with take_along_axis). Delegates to reference.sort_index(axis: slab_axis): reference-shaped, the axis-local rank order within the slab axis.

Returns:

  • (CArray)

    reference-shaped int64



218
219
220
# File 'lib/carray/slab_iterator.rb', line 218

def sort_index
  @reference.sort_index(axis: single_sort_axis(:sort_index))
end

#wmean(weights) ⇒ CArray

Per-slab weighted mean, weights shaped like the reference.

Returns:



238
239
240
# File 'lib/carray/slab_iterator.rb', line 238

def wmean (weights)
  @reference.wmean(weights, axis: @slab_axes)
end

#wsum(weights) ⇒ CArray

Per-slab weighted sum, weights shaped like the reference.

Returns:



231
232
233
# File 'lib/carray/slab_iterator.rb', line 231

def wsum (weights)
  @reference.wsum(weights, axis: @slab_axes)
end