Class: Statsample::Histogram

Inherits:
Object
  • Object
show all
Includes:
Enumerable, GetText
Defined in:
lib/statsample/histogram.rb

Overview

A histogram consists of a set of bins which count the number of events falling into a given range of a continuous variable x.

This implementations follows convention of GSL for specification.

* Verbatim: *

The range for bin[i] is given by range[i] to range[i+1]. 
For n bins there are n+1 entries in the array range. 
Each bin is inclusive at the lower end and exclusive at the upper end. 
Mathematically this means that the bins are defined 
by the following inequality,

 bin[i] corresponds to range[i] <= x < range[i+1]

Here is a diagram of the correspondence between ranges and bins
on the number-line for x,

    [ bin[0] )[ bin[1] )[ bin[2] )[ bin[3] )[ bin[4] )
 ---|---------|---------|---------|---------|---------|---  x
  r[0]      r[1]      r[2]      r[3]      r[4]      r[5]

In this picture the values of the range array are denoted by r. 
On the left-hand side of each bin the square bracket ‘[’ denotes 
an inclusive lower bound ( r <= x), and the round parentheses ‘)’ 
on the right-hand side denote an exclusive upper bound (x < r). 
Thus any samples which fall on the upper end of the histogram are 
excluded. 
If you want to include this value for the last bin you will need to 
add an extra bin to your histogram.

Reference:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(p1, min_max = false, opts = Hash.new) ⇒ Histogram

Returns a new instance of Histogram.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/statsample/histogram.rb', line 67

def initialize(p1, min_max=false, opts=Hash.new)
  
  if p1.is_a? Array
    range=p1
    @n_bins=p1.size-1
  elsif p1.is_a? Integer
    @n_bins=p1
  end
  
  @bin=[0.0]*(@n_bins)
  if(min_max)
    min, max=min_max[0], min_max[1]
    range=Array.new(@n_bins+1)
    (@n_bins+1).times {|i| range[i]=min+(i*(max-min).quo(@n_bins)) }
  end
  range||=[0.0]*(@n_bins+1)
  set_ranges(range)
  @name=""
  opts.each{|k,v|
  self.send("#{k}=",v) if self.respond_to? k
  }
end

Instance Attribute Details

#binObject (readonly)

Returns the value of attribute bin.



63
64
65
# File 'lib/statsample/histogram.rb', line 63

def bin
  @bin
end

#nameObject

Returns the value of attribute name.



62
63
64
# File 'lib/statsample/histogram.rb', line 62

def name
  @name
end

#rangeObject (readonly)

Returns the value of attribute range.



64
65
66
# File 'lib/statsample/histogram.rb', line 64

def range
  @range
end

Class Method Details

.alloc(n_bins, range = nil, opts = Hash.new) ⇒ Object

Alloc n_bins, using range as ranges of bins



44
45
46
47
# File 'lib/statsample/histogram.rb', line 44

def alloc(n_bins, range=nil, opts=Hash.new)
  Histogram.new(n_bins, range, opts)
  
end

.alloc_uniform(n_bins, p1 = nil, p2 = nil) ⇒ Object

Alloc n_bins bins, using p1 as minimum and p2 as maximum



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/statsample/histogram.rb', line 50

def alloc_uniform(n_bins, p1=nil,p2=nil)
  if p1.is_a? Array
    min,max=p1
  else
    min,max=p1,p2
  end
  range=max - min
  step=range / n_bins.to_f
  range=(n_bins+1).times.map {|i| min + (step*i)}
  Histogram.new(range)
end

Instance Method Details

#binsObject

Number of bins



90
91
92
# File 'lib/statsample/histogram.rb', line 90

def bins
  @n_bins
end

#eachObject



125
126
127
128
129
130
131
# File 'lib/statsample/histogram.rb', line 125

def each
  bins.times.each do |i|
    r=get_range(i)
    arg={:i=>i, :low=>r[0],:high=>r[1], :middle=>(r[0]+r[1]) / 2.0,  :value=>@bin[i]}
    yield arg
  end
end

#estimated_meanObject Also known as: mean



144
145
146
147
148
149
150
151
# File 'lib/statsample/histogram.rb', line 144

def estimated_mean
  sum,n=0,0
  each do |v|
    sum+= v[:value]* v[:middle]
    n+=v[:value]
  end
  sum / n
end

#estimated_standard_deviationObject Also known as: sigma



141
142
143
# File 'lib/statsample/histogram.rb', line 141

def estimated_standard_deviation
  Math::sqrt(estimated_variance)
end

#estimated_varianceObject



132
133
134
135
136
137
138
139
140
# File 'lib/statsample/histogram.rb', line 132

def estimated_variance
  sum,n=0,0
  mean=estimated_mean
  each do |v|
    sum+=v[:value]*(v[:middle]-mean)**2
    n+=v[:value]
  end
  sum / (n-1)
end

#get_range(i) ⇒ Object



110
111
112
# File 'lib/statsample/histogram.rb', line 110

def get_range(i)
  [@range[i],@range[i+1]]
end

#increment(x, w = 1) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/statsample/histogram.rb', line 94

def increment(x, w=1)
  if x.respond_to? :each
    x.each{|y| increment(y,w) }
  elsif x.is_a? Numeric
    (range.size-1).times do |i|
      if x>=range[i] and x<range[i+1]
        @bin[i]+=w
        break
      end
    end
  end
end

#maxObject



113
114
115
# File 'lib/statsample/histogram.rb', line 113

def max
  @range.last
end

#max_valObject



119
120
121
# File 'lib/statsample/histogram.rb', line 119

def max_val
  @bin.max
end

#minObject



116
117
118
# File 'lib/statsample/histogram.rb', line 116

def min
  @range.first
end

#min_valObject



122
123
124
# File 'lib/statsample/histogram.rb', line 122

def min_val
  @bin.min
end

#report_building(generator) ⇒ Object



160
161
162
163
# File 'lib/statsample/histogram.rb', line 160

def report_building(generator)
  hg=Statsample::Graph::Histogram.new(self)
  generator.parse_element(hg)
end

#report_building_text(generator) ⇒ Object



164
165
166
167
168
169
# File 'lib/statsample/histogram.rb', line 164

def report_building_text(generator)
  @range.each_with_index do |r,i|
    next if i==@bin.size
    generator.text(sprintf("%5.2f : %d", r, @bin[i]))
  end
end

#set_ranges(range) ⇒ Object



106
107
108
109
# File 'lib/statsample/histogram.rb', line 106

def set_ranges(range)
  raise "Range size should be bin+1" if range.size!=@bin.size+1
  @range=range
end

#sum(start = nil, _end = nil) ⇒ Object



155
156
157
158
159
# File 'lib/statsample/histogram.rb', line 155

def sum(start=nil,_end=nil)
  start||=0
  _end||=@n_bins-1
  (start.._end).inject(0) {|ac,i| ac+@bin[i]}
end