Module: Halton

Defined in:
lib/halton.rb

Overview

The Halton module provides methods for generating Halton sequences, a deterministic low discrepancy sequence that appears to be random. The uniform distribution and repeatability makes the sequence ideal for choosing sample points or placing objects in 2D or 3D space.

grid = 10.times.map {10.times.map {"."}}
Halton.each(2, 3).take(26).zip("A".."Z") do |(x, y), c|
  grid[y * 10][x * 10] = c
end
grid.each {|row| puts row.join(" ")}

Outputs:

. . R . . I . . . .
. L . . . . U C . .
X . . F . . . . . O
. . . J . A . . . .
. D . . . . M S . .
P . . . V . . . G .
. . B . . Y . . . .
. T . . . . E . K .
H . . . N . . . . W
. . . Z . Q . . . .

Defined Under Namespace

Classes: Sequence

Class Method Summary collapse

Class Method Details

.each(base, *bases) ⇒ Object

:call-seq: Halton.each(base) {|n| … } Halton.each(base_x, base_y) {|x, y| … } Halton.each(base_x, base_y, base_z) {|x, y, z| … } Halton.each(*bases) {|*n| … } Halton.each(*bases) -> Enumerator

Implements the fast generation of Halton sequences. The method of generation is adapted from “Fast, portable, and reliable algorithm for the calculation of Halton numbers” by Miroslav Kolář and Seamus F. O’Shea.

The numbers yielded will be in the range > 0 and < 1.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/halton.rb', line 71

def self.each(base, *bases)
  return to_enum(__method__, base, *bases) unless block_given?

  if bases.empty?
    seq = Sequence.new(base)
    loop {yield seq.next}
    return nil
  end

  if bases.length == 1
    x = Sequence.new(base)
    y = Sequence.new(bases.first)
    loop {yield x.next, y.next}
    return nil
  end

  if bases.length == 2
    x = Sequence.new(base)
    y = Sequence.new(bases.first)
    z = Sequence.new(bases.last)
    loop {yield x.next, y.next, z.next}
    return nil
  end

  seqs = bases.unshift(base).map {|b| Sequence.new(b)}
  loop {yield(*seqs.map(&:next))}
  nil
end