Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [ 22 ] 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

2.13. Вычисление логарифмов 83

eval {

$у = tan($pi/2), } or return undef,

> Смотри также-

Описание функций sin, cos и atan2 вperlfunc(l). Тригонометрия в контексте комплексных чисел рассматривается в рецепте 2.15, а использование eval для перехвата исключений - в рецепте 10.12.

2.13. Вычисление логарифмов

Проблема

Требуется вычислить логарифм по различным основаниям.

Решение

Для натуральных логарифмов (по основанию е) существует встроенная функция log:

$log e = log(VALUE),

Чтобы вычислить логарифм по основанию 10, воспользуйтесь функцией log 10 модуля P0S1X:

use POSIX qw(loglO), $log 10 = loglO(VALUE),

Для других оснований следует использовать соотнощение:

1од„(х) = 1одДх)/1од(п)

где X - число, логарифм которого вычисляется, п - нужное основание, а е - основание натуральных логарифмов.

sub log base {

my ($base, lvalue) = @ , return log($value)/log($base),

Комментарий

Функция log base позволяет вычислять логарифмы по любому основанию. Если основание заранее известно, намного эффективнее вычислить его натуральный логарифм заранее и сохранить для последующего использования, вместо того чтобы каждый раз пересчитывать его заново.

# Определение log base см выше

$answer = log base(10, 10, 10 000),

print loglOdO, 100) = $answer\n , log10(10,000) = 4



> Смотри также-

Описание функции log вperlfunc(\); документация по стандартному модулю POSIX.

2.14. Умножение матриц

Проблема

Требуется перемножить два двумерных массива. Умножение матриц часто используется в математических и инженерных вычислениях.

Решение

Воспользуйтесь модулями PDL с CPAN. Модули PDL (Perl Data Language, то есть «язык данных РегЬ) содержат быстрые и компактные матричные и математические функции:

use PDL;

# $а и $b - объекты pdl $с = $а . $Ь;

Альтернативный вариант - самостоятельно реализовать алгоритм умножения матриц для двумерных массивов:

sub mmult {

my ($m1,$m2) = @ ;

my (Smirows, $m1cols) = matdim($m1);

my ($m2rows, $m2cols) = matdim($(n2);

unless (Smicols == $m2rows) { # Инициировать исключение

die "IndexError: matrices dont match: $m1cols != $m2rows";

my $result = []; my ($1, $j, $k),

for $i (range($m1rows)) { for $j (range($m2cols)) { for $k (range($m1cols)) {

В модуле Math::Complex для вычисления логарифмов по произвольному основанию существует функция logn(), поэтому вы можете написать:

use Math::Complex;

printf log2(1024) = %lf\n", logn(1024, 2); ft Обратите внимание

# на порядок аргументов

1од2(1024) = 10.000000

хотя комплексные числа в вычислениях не используются. Функция не очень эффективна, однако в будущем планируется переписать Math;:Complex на С для повышения быстроты.



2.14. Умножение матриц 85

$result->[$i][$]] += $m1->[$i][$k] . $m2->[$k][$]];

return Sresult;

sub range {0 .. ($ [0] - 1 }

sub veclen {

my $ary ref = $ [0]; my type = ref $ary ref;

if ($type ne "ARRAY") {die "$type is bad array ref for $ary ref" } return scalar(@$ary ref);

sub matdim {

my Smatrix = $ [0];

my $rows = veclen($matrix);

my $cols = veclen($matrix->[0]);

return ($rows, $cols),

Комментарий

Если у вас установлена библиотека PDL, вы можете воспользоваться ее молниеносными числовыми операциями. Они требуют значительно меньше памяти и ресурсов процессора, чем стандартные операции с массивами Perl. При использовании объе1сгов PDL многие числовые операторы (например, + и *) перегружаются и работают с конкретными типами операндов (например, оператор * выполняет так называемое скалярное умножение). Для умножения матриц используется перегруженный оператор х.

use PDL;

$а = pdl [

[ 3, 2, 3 ], [ 5, 9, 8 ],

$b = pdl [ [ 4, 7 ], [ 9, 3 ], [ 8, 1 ],

$c = $a X $b; # Перегруженный оператор x

Если библиотека PDL недоступна или вы не хотите привлекать ее для столь тривиальной задачи, матрицы всегда можно перемножить вручную:



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [ 22 ] 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242