Class: MoreMath::Subset

Inherits:
Object show all
Includes:
Enumerable, RankingCommon
Defined in:
lib/more_math/subset.rb

Overview

A subset represents a selection of elements from a set, where each element can either be included (1) or excluded (0) from the subset. Subsets are ranked in lexicographic order, allowing efficient enumeration and indexing.

Examples:

Create a subset of size 3

subset = Subset.new(3)
# => #<Subset:0x6ae34 @last=7, @rank=0, @size=3>

Create a subset with specific rank

subset = Subset.new(3, 5)
# => #<Subset:0x6ae34 @last=7, @rank=5, @size=3>

Get the subset as an array of indices

subset = Subset.new(3, 5)
subset.value
# => [0, 2]

Project onto actual data

subset = Subset.new(3, 5)
subset.project(['a', 'b', 'c'])
# => ['a', 'c']

Instance Attribute Summary

Attributes included from RankingCommon

#collection, #last, #rank, #size

Class Method Summary collapse

Instance Method Summary collapse

Methods included from RankingCommon

#each, #each!, #next, #next!, #pred, #pred!, #random, #random!

Constructor Details

#initialize(size, rank = 0) ⇒ Subset

Returns a Subset instance for a collection of size size with the rank rank. Creates a new Subset instance of size (and ranked with rank).

Parameters:

  • size (Integer)

    The size of the subset

  • rank (Integer) (defaults to: 0)

    The rank of the subset (default: 0)



36
37
38
39
# File 'lib/more_math/subset.rb', line 36

def initialize(size, rank = 0)
  @size, self.rank = size, rank
  @last = (1 << size) - 1
end

Class Method Details

.for(collection, rank = 0) ⇒ Subset

Creates a new Subset instance for a collection of size size with the rank rank.

Parameters:

  • collection (Object)

    collection to use for projection

  • rank (Integer) (defaults to: 0)

    the rank of this subset (default: 0)

Returns:

  • (Subset)

    new subset instance



47
48
49
50
51
# File 'lib/more_math/subset.rb', line 47

def self.for(collection, rank = 0)
  subset = new(collection.size, rank)
  subset.instance_variable_set(:@collection, collection)
  subset
end

.power_set(collection) ⇒ Array<Array>

Returns the power set of the collection collection.

Parameters:

  • collection (Object)

    the collection to generate power set for

Returns:

  • (Array<Array>)

    array of all possible subsets



57
58
59
# File 'lib/more_math/subset.rb', line 57

def self.power_set(collection)
  self.for(collection).map(&:value)
end

Instance Method Details

#project(data = nil) ⇒ Array

This method maps elements from a given dataset based on the subset’s indices determined by its rank and returns the result, while ensuring the input data size matches the subset’s size.

Parameters:

  • data (Object) (defaults to: nil)

    data to project onto (optional)

Returns:

  • (Array)

    projected result

Raises:

  • (ArgumentError)


91
92
93
94
95
# File 'lib/more_math/subset.rb', line 91

def project(data = nil)
  data ||= @collection || (0...size).to_a
  raise ArgumentError, "data size is != #{size}!" if data.size != size
  value.map { |i| data[i] }
end

#rank=(m) ⇒ Integer

Assigns m to the rank attribute of this Subset instance. That implies that the indices produced by a call to the Subset#value method of this instance is the subset ranked with this new rank.

Parameters:

  • m (Integer)

    new rank value

Returns:

  • (Integer)

    assigned rank



67
68
69
# File 'lib/more_math/subset.rb', line 67

def rank=(m)
  @rank = m % (1 << size)
end

#valueArray<Integer>

Returns the subset for rank #rank and #collection. (If no collection was set it applies to the array [ 0, 1, …, size - 1 ] instead.)

Returns:

  • (Array<Integer>)

    array of indices representing this subset



75
76
77
78
79
80
81
82
83
# File 'lib/more_math/subset.rb', line 75

def value
  result = []
  c = @collection || (0...size).to_a
  r = @rank
  size.times do |i|
    r[i] == 1 and result << c[i]
  end
  result
end