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.

[View source] [View on GitHub]

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/statsample/histogram.rb', line 71

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.

[View on GitHub]

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

def bin
  @bin
end

#nameObject

Returns the value of attribute name.

[View on GitHub]

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

def name
  @name
end

#rangeObject (readonly)

Returns the value of attribute range.

[View on GitHub]

66
67
68
# File 'lib/statsample/histogram.rb', line 66

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

[View source] [View on GitHub]

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

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

[View source] [View on GitHub]

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

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

[View source] [View on GitHub]

95
96
97
# File 'lib/statsample/histogram.rb', line 95

def bins
  @n_bins
end

#eachObject

[View source] [View on GitHub]

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

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

[View source] [View on GitHub]

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

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

[View source] [View on GitHub]

150
151
152
# File 'lib/statsample/histogram.rb', line 150

def estimated_standard_deviation
  Math::sqrt(estimated_variance)
end

#estimated_varianceObject

[View source] [View on GitHub]

141
142
143
144
145
146
147
148
149
# File 'lib/statsample/histogram.rb', line 141

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

[View source] [View on GitHub]

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

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

#increment(x, w = 1) ⇒ Object

[View source] [View on GitHub]

99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/statsample/histogram.rb', line 99

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

[View source] [View on GitHub]

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

def max
  @range.last
end

#max_valObject

[View source] [View on GitHub]

128
129
130
# File 'lib/statsample/histogram.rb', line 128

def max_val
  @bin.max
end

#minObject

[View source] [View on GitHub]

125
126
127
# File 'lib/statsample/histogram.rb', line 125

def min
  @range.first
end

#min_valObject

[View source] [View on GitHub]

131
132
133
# File 'lib/statsample/histogram.rb', line 131

def min_val
  @bin.min
end

#report_building(generator) ⇒ Object

[View source] [View on GitHub]

169
170
171
172
# File 'lib/statsample/histogram.rb', line 169

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

#report_building_text(generator) ⇒ Object

[View source] [View on GitHub]

173
174
175
176
177
178
# File 'lib/statsample/histogram.rb', line 173

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

[View source] [View on GitHub]

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

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

[View source] [View on GitHub]

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

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