Хэл Фултон - Программирование на языке Ruby
- Название:Программирование на языке Ruby
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2007
- Город:Москва
- ISBN:5-94074-357-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Хэл Фултон - Программирование на языке Ruby краткое содержание
Ruby — относительно новый объектно-ориентированный язык, разработанный Юкихиро Мацумото в 1995 году и позаимствовавший некоторые особенности у языков LISP, Smalltalk, Perl, CLU и других. Язык активно развивается и применяется в самых разных областях: от системного администрирования до разработки сложных динамических сайтов.
Книга является полноценным руководством по Ruby — ее можно использовать и как учебник, и как справочник, и как сборник ответов на вопросы типа «как сделать то или иное в Ruby». В ней приведено свыше 400 примеров, разбитых по различным аспектам программирования, и к которым автор дает обстоятельные комментарии.
Издание предназначено для программистов самого широкого круга и самой разной квалификации, желающих научиться качественно и профессионально работать на Ruby.
Программирование на языке Ruby - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Пусть дан массив x, вычислим среднее значение по всем элементам массива. На самом деле есть три общеупотребительные разновидности среднего значения. Среднее арифметическое — это то, что мы называем средним в обыденной жизни. Среднее гармоническое — это число элементов, поделенное на сумму обратных к ним. И, наконец, среднее геометрическое — это корень n-ой степени из произведения n значений. Вот эти определения, воплощенные в коде:
def mean(x)
sum=0
x.each {|v| sum += v}
sum/x.size
end
def hmean(x)
sum=0
x.each {|v| sum += (1.0/v)}
x.size/sum
end
def gmean(x)
prod=1.0
x.each {|v| prod *= v}
prod**(1.0/x.size)
end
data = [1.1, 2.3, 3.3, 1.2, 4.5, 2.1, 6.6]
am = mean(data) # 3.014285714
hm = hmean(data) # 2.101997946
gm = gmean(data) # 2.508411474
Медианой набора данных называется значение, которое оказывается приблизительно в середине отсортированного набора (ниже приведен код для вычисления медианы). Примерно половина элементов набора меньше медианы, а другая половина — больше. Ясно, что такая статистика показательна не для всякого набора.
def median(x)
sorted = x.sort
mid = x.size/2
sorted[mid]
end
data = [7,7,7,4,4,5,4,5,7,2,2,3,3,7,3,4]
puts median(data) # 4
Мода набора данных — это наиболее часто встречающееся в нем значение. Если такое значение единственно, набор называется унимодальным , в противном случае — мультимодальным. Мультимодальные наборы более сложны, здесь мы их рассматривать не будем. Интересующийся читатель может обобщить и улучшить приведенный ниже код:
def mode(x)
f = {} # Таблица частот.
fmax = 0 # Максимальная частота.
m = nil # Мода.
x.each do |v|
f[v] ||= 0
f[v] += 1
fmax,m = f[v], v if f[v] > fmax
end
return m
end
data = [7,7,7,4,4,5,4,5,7,2,2,3,3,7,3,4]
puts mode(data) # 7
5.26. Дисперсия и стандартное отклонение
Дисперсия — это мера «разброса» значений из набора. (Здесь мы не различаем смещенные и несмещенные оценки.) Стандартное отклонение, которое обычно обозначается буквой σ, равно квадратному корню из дисперсии.
Data = [2, 3, 2, 2, 3, 4, 5, 5, 4, 3, 4, 1, 2]
def variance(x)
m = mean(x)
sum = 0.0
x.each {|v| sum += (v-m)**2 }
sum/x.size
end
def sigma(x)
Math.sqrt(variance(x))
end
puts variance(data) # 1.461538462
puts sigma(data) # 1.20894105
Отметим, что функция varianceвызывает определенную выше функцию mean.
5.27. Вычисление коэффициента корреляции
Коэффициент корреляции — одна из самых простых и полезных статистических мер. Он измеряет «линейность» набора, состоящего из пар (x, у), и изменяется от -1.0 (полная отрицательная корреляция) до +1.0 (полная положительная корреляция).
Для вычисления воспользуемся функциями meanи sigma(стандартное отклонение), которые были определены в разделах 5.25 и 5.26. О смысле этого показателя можно прочитать в любом учебнике по математической статистике.
В следующем коде предполагается, что есть два массива чисел одинакового размера:
def correlate(x,y)
sum = 0.0
x.each_index do |i|
sum += x[i]*y[i]
end
xymean = sum/x.size.to_f
xmean = mean(x)
ymean = mean(y)
sx = sigma(x)
sy = sigma(y)
(xymean-(xmean*ymean))/(sx*sy)
end
a = [3, 6, 9, 12, 15, 18, 21]
b = [1.1, 2.1, 3.4, 4.8, 5.6]
с = [1.9, 1.0, 3.9, 3.1, 6.9]
c1 = correlate(a,a) # 1.0
c2 = correlate(a,a.reverse) # -1.0
c3 = correlate(b,c) # 0.8221970228
Приведенная ниже версия отличается лишь тем, что работает с одним массивом, каждый элемент которого — массив, содержащий пару (x, у):
def correlate2(v)
sum = 0.0
v.each do |a|
sum += a[0]*a[1]
end
xymean = sum/v.size.to_f
x = v.collect {|a| a[0]}
y = v.collect {|a| a[1]}
xmean = mean(x)
ymean = mean(y)
sx = sigma(x)
sy = sigma(y)
(xymean-(xmean*ymean))/(sx*sy)
end
d = [[1,6.1], [2.1,3.1], [3.9,5.0], [4.8,6.2]]
c4 = correlate2(d) # 0.2277822492
И, наконец, в последнем варианте предполагается, что пары (x, у) хранятся в хэше. Код основан на предыдущем примере:
def correlate_h(h)
correlate2(h.to_a)
end
e = { 1 => 6.1, 2.1 => 3.1, 3.9 => 5.0, 4.8 => 6.2}
c5 = correlated(e) # 0.2277822492
5.28. Генерирование случайных чисел
Если вас устраивают псевдослучайные числа, вам повезло. Именно они предоставляются в большинстве языков, включая и Ruby.
Метод randиз модуля Kernel возвращает псевдослучайное число x с плавающей точкой, отвечающее условиям x >= 0.0и x < 1.0. Например (вы можете получить совсем другое число):
a = rand # 0.6279091137
Если при вызове задается целочисленный параметр max, то возвращается целое число из диапазона 0...max(верхняя граница не включена). Например:
n = rand(10) # 7
Чтобы «затравить» генератор случайных чисел (задать начальное значение — seed), применяется метод srandиз модуля Kernel, который принимает один числовой параметр. Если не передавать никакого значения, то метод srandсамостоятельно изготовит затравку, учитывая (среди прочего) текущее время. Если же параметр передан, то именно он и становится затравкой. Это бывает полезно при тестировании, когда для воспроизводимости результатов многократно вызываемая программа должна получать одну и ту же последовательность псевдослучайных чисел.
srand(5)
i, j, k = rand(100), rand(100), rand(100)
# 26, 45, 56
srand(5)
l, m, n = rand(100), rand(100), rand(100)
# 26, 45, 56
5.29. Кэширование функций с помощью метода memoize
Пусть имеется вычислительно сложная математическая функция, которую нужно многократно вызывать по ходу работы программы. Если быстродействие критично и при этом можно пожертвовать небольшим количеством памяти, то имеет смысл сохранить результаты вычисления функции в таблице и обращаться к ней во время выполнения. (Тут неявно предполагается, что функция будет часто вызываться с одними и теми же параметрами, то есть получается, что мы «выбрасываем» результат дорогостоящего вычисления и снова повторяем его позже.) Такая техника иногда называется запоминанием (memoizing), отсюда и название библиотеки memoize.
Эта библиотека не входит в стандартный дистрибутив, поэтому придется установить ее вручную.
В следующем примере демонстрируется сложная функция zeta. Она применяется при решении одной задачи из области популяционной генетики, но вдаваться в объяснения мы не станем.
require 'memoize'
include Memoize
def zeta(x,y,z)
lim = 0.0001
gen = 0
loop do
gen += 1
p,q = x + y/2.0, z + y/2.0
x1, y1, z1 = p*p*1.0, 2*p*q*1.0, q*q*0.9
Интервал:
Закладка: