\documentclass[12pt,fleqn,a4paper]{book}
%
% Packages used:
%
\usepackage[koi8-r]{inputenc}
\usepackage[russian,english]{babel}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsfonts}
\usepackage{amsthm}
\advance\textheight by 5mm
%
% Common customization:
%
\input defs
%
\renewcommand\mod{\mathrm{mod}\ }
%
% The document
%
\begin{document}
\selectlanguage{russian}
\lecture{4}{Параллельные алгоритмы для вычисления определителя и арифметических операций}{Е.~Петренко}
%
% The lecture
%
%\setlength{\arrayrulewidth}{0.8pt}     
%\setlength{\doublerulesep}{6pt}        
%\renewcommand{\arraystretch}{1.15}     

\section{Вычисление определителя}

Пусть $A$ --- матрица размерами $n\times n$. Требуется вычислить определитель этой 
матрицы. Алгоритм будет использовать $\poly(\log n)$ процессоров.

Алгоритм будет одновременно вычислять определитель и искать обратную матрицу.
Заметим, что обратная матрица к матрице $B$ выглядит следующим образом:
$$
B^{-1}=\frac{1}{\det B}
        \left(
            \begin{array}{c|c}
               B^{11} & \cdots \\
               \hline 
               \vdots & \ddots
            \end{array}
        \right) .
$$
Пусть $B^{(i)}$ --- правый нижний $i\times i$ угол матрицы $B$.
Тогда
$$
   (B^{-1})_{11} = \frac{\det B^{(n-1)}}{\det B^{(n)}},
$$
а в общем случае
$$
   \left({B^{(i)}}^{-1}\right)_{11} = \frac{\det B^{(i-1)}}{\det B^{(i)}}.
$$

Положим $\det Z=1$, где матрица $Z$ --- размерности $0\times 0$.
Имеем
$$
\det B = \det B^{(n)} = \frac{\det B^{(n-1)}}{\left(\left(B^{(n)}\right)^{-1}\right)_{11}} = \ldots = 
      \frac{1}{\prod\limits^n_{i=1} {\left( {B^{(i)}}^{-1} \right)}_{11} }.
$$
%$$
%\det B^{(1)} = \det b = \frac{1}{b^{-1}}
%$$


При помощи этого тождества будем искать определитель символьной матрицы $E-xA$
(и из него извлечем $\det A$).
Поскольку $\deg\det(E-xA) \le n$,
все вычисления можно проводить по $\mod x^{n+1}$:
$$
(E-xA^{(k)})^{-1} = \sum\limits_{i=0}^{k-1}{(xA)^i \pmod{x^{n+1}}}
$$
Возводить в степень и складывать матрицы можно при помощи двоичного дерева.
Сложение многочленов производим поэлементно, умножение многочленов 
не используется:
$
(xA)^i = x^iA^i.
$

Так мы вычислим $\prod\limits_{i=0}^n({B^{(i)}}^{-1})_{11}$. 
Для получения $\det(E-xA)$ остается обратить полученный многочлен $p(x)$.
Пусть
$$
p(x) = \mathrm{const}\cdot(1-xq(x)).
$$
Тогда имеет место равенство
\begin{equation}
(1-xq(x))^{-1} = \sum\limits_{i=0}^{n}{(xq(x))^i\pmod{x^{n+1}}}
\label{1-xq}
\end{equation}
Для проверки этого утверждения достаточно раскрыть сумму. 
(Если же $p(x)$ не представим в таком виде, то
$
\exists k:\ p(x) = x^k\cdot \mathrm{const}(1-xq(x))
$;
тогда при помощи \ref{1-xq} мы можем обратить все, кроме $x^k$.)

Итак, мы нашли $\det(E-xA)$
(либо нечто, что при домножении на $x^k$ дает $x^k\cdot \det(E-xA)$).
Коэффициент при $x^n$ этого многочлена и есть $\det A$:
$$
\lim\limits_{n \rightarrow +\infty}\frac{\det(E-xA)}{(-x)^n} = 
\lim\limits_{n \rightarrow +\infty}\det{\left(\frac{E}{(-x)^n}+A\right)} = \det A;
$$
(аналогично, если вычислили <<с точностью до $x^k$>>:
$$
\lim\limits_{x\rightarrow+\infty}\frac{\det(E-xA)x^k}{(-x)^nx^k} = 
\lim\limits_{x\rightarrow+\infty}\det{\left(\frac{E}{(-x)^nx^k}+A\right)} = \det A).
$$

%Выбираем все таким образом, чтобы существовал $(E-xA)^{-1}$. Нужно, чтобы:
%$\det(E-xA)=\det((E-xA)^{(n-1)})\cdot((E-xA)^{-1}_{11})^{-1}$
%
%Пусть $p(x)=0$, т.е. $p(x) = \prod{((E-xA)^{-1}_{11})^{-1}} = 0$. В силу того, что
%$p_1^{-1},p_2^{-1},/ldots,p_k^{-1}$ --- обратимы, следовательно, они не могут обратиться
%в ноль, следовательно, их произведение не может обратиться в ноль, в силу того, что
%оно тоже получается обратимым. Распишем формулу:
%$$
%\det(E-xA){(E-xA)}^{-1}_{11} = \det(E-xA)^{(n-1)} = \cdots = 1
%$$
%В результате:
%$$
%\det(E-xA)\cdot\prod\limits_{i=1}^{n}{({(E-xA)^{-1}})^{(i)}_{11}})^{-1}
%$$
%Вычислим произведение. 
%
%Умеем вычислять определитель. Для вычисления обратной матрицы нужно вычислить $n^2+1$ 
%определителей эту операцию можно производить параллельно. 

Мы сделали это за логарифмическое время,
если время измерять в арифметических операциях.
Осталось научиться параллелизовать арифметические операции.
(Заметим, кстати, что коэффициенты наших многочленов были порядка
$O(b)\cdot 2^{O(n)}$, где $b$ --- количество битов в исходных коэффициентах.)

\section{Вычисление суммы и произведения целых чисел}

\begin{lemma}
Пусть $\diamond$ --- ассоциативная операция, тогда одновременное вычисление 
всех $(a_1\diamond a_2\cdots\diamond a_i)$ для $i=1,2,\ldots,n$ можно произвести 
за логарифмическое время на $O(n/\log n)$ процессорах. 
\end{lemma}
\begin{proof}\hfill

\gap

\end{proof}

{\bfseries\hrule}

\medskip
\noindent
{\LARGE\itshape{\bfseries Disclaimer:} все написанное ниже мне проверить
не удалось, поскольку не удалось понять конспектирующего. Текст приводится
<<as is>>. Если появится альтернативный конспект, я готов поместить сюда его.\\\phantom{.}\hfill\ --$\,$--$\,$Э.А.}

\subsection{Вычисление суммы}
$$
a_i + b_i + c_i \rightarrow d_i, c_{i+1} 
$$


Линейно, хотим сделать за $\log $. 
$$
\begin{array}{c} 
  p_i = a_i \vee b_i //
  g_i = a_i \wedge b_i //
\label{pigi}
\end{array}
$$

Операция сложения с переносом для двоичных чисел. $g_i$ --- перенос будет, 
$p_i$ --- перенос перейдет.
По \ref{pigi} получим 
$$
c_i = g_i \vee (p_i \wedge c_{i-1})
$$


Определим операцию:
$$
(x,y)\diamond(x',y') = (x'\vee (y'\wedge x), y'\wedge y)
$$

Проверим ассоциативность.
$$
\begin{array}{c}
   (c_i, -) = (c_{i-1} , - ) \diamond ( g_i, p_i) //
   \Rightarrow //
   (\circ, \circ)\diamond(g_1, p_1)\diamond\cdots\diamond(g_i,p_i)
\end{array}
$$
$\diamond$ --- ассоциативная операция. Следовательно, можно вычислить за $\log$. Для вычисления
суммы всего числа можно выполнить этот процесс в каждом разряде. Построили алгоритм сложения
за $\log$ шагов. 

\subsection{Вычисление произведения}
Умножение --- это сложения и сдвиги. Алгоритм умножения <<в столбик>>. Для каждого разряда 
вычисляем отдельно. Нужно вычислить сумму $n$ чисел из $2n$ битов. Каждый бит 
$c_{ij} = a_i\wedge b_i$ или нуль.

Просто сложить все числа. Сложность будет $\log^2$. Есть другое решение:
рассмотрим троичное дерево
$$
\oplus(a, b, c) = (e, f)
$$
Высота дерева $\log_{\frac 32}$
$$
\begin{array}{lc}
  x_i, y_i, z_i: & (x_i, y_i, z_i) \rightarrow (u_i, v_i)\\
  & v_i=x_i+y_i+z_i \pmod{2}\\
  & u_i=x_i+y_i+z_i \div 2
\end{array}
$$

$ a_i + b_i + c_i = \overline{e_if_i} $ --- просто побитовое сложение. Результат суммы
трех двоичных чисел влезет в два двоичных числа. 
Когда остаются только 2 числа, применим обычное сложение. 



\end{document}
