3 Текст процедур расчета
require "gsl"
require "Qt"
puts "zlab in console!"
class TestRandom
def initialize (realization_size = :small, histogram_bins_count = [[7],[7,7],[7,7,7]], range = 0.0..1.0, k = 4)
@histogram_bins_count = histogram_bins_count
@general_range = range
@k = k
case realization_size
when :small
@elements_count_factor = Random.rand(7..10)
when :medium
@elements_count_factor = Random.rand(30..90)
when :large
@elements_count_factor = Random.rand(300..900)
end
random_generators = [Random.new, Random.new, Random.new]
@arrays_sizes = Array.new()
@arrays_sizes << @elements_count_factor * @histogram_bins_count[0][0]
@arrays_sizes << @elements_count_factor * @histogram_bins_count[1][0] * @histogram_bins_count[1][1]
@arrays_sizes << @elements_count_factor * @histogram_bins_count[2][0] * @histogram_bins_count[2][1] * @histogram_bins_count[2][2]
@raw_random_data_arrays = Array.new
@raw_random_data_arrays << [Array.new]
@raw_random_data_arrays << [Array.new, Array.new]
@raw_random_data_arrays << [Array.new, Array.new, Array.new]
@arrays_sizes[0].to_i.downto(0) do |number|
@raw_random_data_arrays[0][0] << random_generators[0].rand(range)
end
@arrays_sizes[1].to_i.downto(0) do |number|
@raw_random_data_arrays[1][0] << random_generators[0].rand(range)
@raw_random_data_arrays[1][1] << random_generators[1].rand(range)
end
@arrays_sizes[2].to_i.downto(0) do |number|
@raw_random_data_arrays[2][0] << random_generators[0].rand(range)
@raw_random_data_arrays[2][1] << random_generators[1].rand(range)
@raw_random_data_arrays[2][2] << random_generators[2].rand(range)
end
@histogram_1d = GSL::Histogram.alloc(@histogram_bins_count[0][0], [range.begin, range.end])
@histogram_2d = GSL::Histogram2d.alloc(@histogram_bins_count[1][0], [range.begin, range.end], @histogram_bins_count[1][1], [range.begin, range.end])
@histogram_3d = GSL::Histogram3d.alloc(@histogram_bins_count[2][0], [range.begin, range.end], @histogram_bins_count[2][1], [range.begin, range.end], @histogram_bins_count[2][2], [range.begin, range.end])
@arrays_sizes[0].downto (0) do |array_index|
@histogram_1d.increment(@raw_random_data_arrays[0][0][array_index] )
end
@arrays_sizes[1].downto (0) do |array_index|
@histogram_2d.increment @raw_random_data_arrays[1][0][array_index],@raw_random_data_arrays[1][1][array_index]
end
@arrays_sizes[2].downto (0) do |array_index|
@histogram_3d.increment @raw_random_data_arrays[2][0][array_index], @raw_random_data_arrays[2][1][array_index], @raw_random_data_arrays[2][2][array_index]
end
end
def uniformity
puts "Uniformity check:"
puts "chi_square:", chi_square_1d
puts "autocorellation", autocorellation_1d
#puts get_1d_sigma
end
def uniform_distribution_probability_in range
(1.0/(@general_range.end - @general_range.begin))*(range.end - range.begin)
end
def chi_square_1d
chi_square = 0
0.upto (@histogram_1d.bins - 1) do |bin_number|
bin_bounds = @histogram_1d.get_range(bin_number)
f_i = ((@arrays_sizes[0] + 1) * (uniform_distribution_probability_in Range.new(bin_bounds[0], bin_bounds[1])))
#puts @histogram_1d.get_range(bin_number)
#puts @histogram_1d[bin_number]
#puts bin_number
chi_square += ((@histogram_1d[bin_number] - f_i ) ** 2)/f_i
end
chi_square
end
def get_1d_mean
result = 0
@raw_random_data_arrays[0][0].each do |item|
result += item
end
result /= @raw_random_data_arrays[0][0].count.to_f
end
def get_1d_sigma
sum1 , sum2 = 0 , 0
@raw_random_data_arrays[0][0].each do |item|
sum1 += item ** 2
sum2 += item
end
sum1 = sum1.to_f/@raw_random_data_arrays[0][0].count
sum2 = sum2.to_f/@raw_random_data_arrays[0][0].count
sum2 = sum2 ** 2
sum1 - sum2
end
def autocorellation_1d
autocorellation = 0
sigma = get_1d_sigma
0.upto(@raw_random_data_arrays[0][0].count - 1 - @k) do |index|
autocorellation += (@raw_random_data_arrays[0][0][index] - 0.5)*(@raw_random_data_arrays[0][0][index+@k] - 0.5)/(@raw_random_data_arrays[0][0].count - @k).to_f
end
autocorellation /= sigma.to_f
end
def sample_moments
result = Array.new
orders = 4
1.upto(orders) do |index|
puts "order "+index.to_s
a_moment = 0
m_moment = 0
mean = get_1d_mean
@raw_random_data_arrays[0][0].each do |item|
a_moment += item ** index
m_moment += (item - mean) ** index
end
result << [a_moment, m_moment]
puts "a: ", a_moment /= @raw_random_data_arrays[0][0].count
puts "mu: ", m_moment /= @raw_random_data_arrays[0][0].count
end
result
end
def plots
GSL::graph(@histogram_1d, "-T X -C -g 3")
h2x = @histogram_2d.xproject
h2y = @histogram_2d.yproject
#printf("%f %f %f %f\n", h2.xsigma, h2.ysigma, hx.sigma, hy.sigma)
GSL::graph(h2x, h2y, "-T X -C -g 3")
h3xy = @histogram_3d.xyproject
h31 = h3xy.xproject
h32 = h3xy.yproject
h3xz = @histogram_3d.xzproject
h33 = h3xz.yproject
#printf("%f %f %f %f\n", h2.xsigma, h2.ysigma, hx.sigma, hy.sigma)
GSL::graph(h31, h32, h33, "-T X -C -g 3")
#GSL::graph(hx, hy, "-T X -C -g 3")
end
end
obj = TestRandom.new(:small)
obj.uniformity
obj.sample_moments
obj.plots
Вывод
В данной лабораторной работе нами был построен датчик равномерно распределенных случайных чисел. Проверка равномерности распределения проводилась на основе построения одномерной гистограммы и выводе результатов распределения для двухмерной и трехмерной выборок в виде табличных данных.
Проверка независимости формируемых случайных чисел проводится с помощью расчета коэффициента автокорреляции (k = 1).
Выборочное значение математического ожидания близко к теоретическому значению M(x) = 0.5 и входит в допустимый диапазон для равномерного распределения. Равномерность распределения во всех случаях подтвердил и критерий X2. Проведенные исследования подтверждают правильность работы построенного датчика.