<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=DVIN</id>
	<title>Алговики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=DVIN"/>
	<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/DVIN"/>
	<updated>2026-10-22T15:52:49Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18800</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18800"/>
		<updated>2016-11-21T13:22:01Z</updated>

		<summary type="html">&lt;p&gt;DVIN: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась собственная параллельная реализация алгоритма, написанная на языке C++ с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Версия MPI - intel opemmpi/1.8.4-icc&lt;br /&gt;
&lt;br /&gt;
Модель используемого CPU - Intel Xeon X5570 2.93GHz&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|Рис. 6 Время работы алгоритма в зависимости от числа процессоров и размерности задачи]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проведём еще одно исследование исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта для меньшего числа процессоров. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:10] с шагом 1;&lt;br /&gt;
*	размерность векторов [20 : 400] с шагом 20.&lt;br /&gt;
На графике 1 приведено время работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramTime.jpg|мини|upright=3|centre|framecentre|1|Рис. 7 Время работы программы в зависимости от числа процессоров и размерности задачи]]&lt;br /&gt;
На графике 2 приведена производительность работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramPerf.jpg|мини|upright=3|centre|framecentre|2|Рис. 8 Производительность программы в зависимости от количество процессоров и размерности задачи]]&lt;br /&gt;
На графике 3 приведена эффективность распараллеливания работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramParEffi.jpg|мини|upright=3|centre|framecentre|3|Рис. 9 Эффективность распараллеливания алгоритма]]&lt;br /&gt;
Оценим значения масштабируемости данной реализации:&lt;br /&gt;
Общей оценкой масштабируемости по числу процессов будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по числу процессов по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По числу процессоров: -0.009265. С увеличением числа процессоров наблюдается слабое снижение эффективности работы параллельной реализации алгоритма.&lt;br /&gt;
Общей оценкой масштабируемости по размеру решаемой задачи будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по размеру решаемой задачи по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По размеру задачи: 0.00002555. При увеличении размерности задачи эффективность алгоритма очень медленно возрастает.&lt;br /&gt;
Общей оценкой масштабируемости будем называть средний размер вклада каждого элемента рассматриваемой области значений в общую оценку по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По двум направлениям: 0.002079.&lt;br /&gt;
[https://bitbucket.org/d_2007_90/gram-schmidt-process/src Реализация алгоритма]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:DVIN&amp;diff=18796</id>
		<title>Обсуждение участника:DVIN</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:DVIN&amp;diff=18796"/>
		<updated>2016-11-21T13:13:29Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* По существу (будет добавляться по мере вычитывания) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:DVIN/Ортогонализация Грамма-Шмидта]] ==&lt;br /&gt;
&lt;br /&gt;
* В разделе 1.3 определение вычислительного ядра можно опустить&lt;br /&gt;
**Исправлено&lt;br /&gt;
&lt;br /&gt;
=== По существу (будет добавляться по мере вычитывания) ===&lt;br /&gt;
&lt;br /&gt;
* Унифицируйте обозначения, а то у Вас в одном месте, например, для скалярного произведения угловые скобки, в другом - просто умножение через точку. И в случае неоднозначности конкретизируйте. Скажем, при нормализации норма там не всякая, а именно согласованная со скалярным произведением, это нужно указывать. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:10, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* Аккуратнее с терминами. Счётное множество вообще-то бесконечно, так что этот термин здесь неуместен. Вообще проверьте всё спеллером. &amp;quot;Линейно независимые&amp;quot; без пробела и т.п. - нехорошо. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:05, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* В Вашем представлении число векторов в системе необязательно равно размерности, но в стартовой вкладке вы даёте оценку при k=N, дайте лучше общую.  --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:04, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* В 1.8 - параллельно можно не только проекции, но и вычитания делать. Поправьте. На сегодня пока всё, завтра снова загляну. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:13, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:49, 16 ноября 2016 (MSK) &lt;br /&gt;
**Исправлено&lt;br /&gt;
* В разделе 2.4 не приведена использованная в экспериментах реализация алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:49, 16 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* Подписи к рисункам в разделе 2.4 довольно странные. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 14:20, 21 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18795</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18795"/>
		<updated>2016-11-21T13:07:46Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась собственная параллельная реализация алгоритма, написанная на языке C++ с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Версия MPI - intel opemmpi/1.8.4-icc&lt;br /&gt;
&lt;br /&gt;
Модель используемого CPU - Intel Xeon X5570 2.93GHz&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|Рис. 6 Время работы алгоритма в зависимости от числа процессоров и размерности задачи]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проведём еще одно исследование исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта для меньшего числа процессоров. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:10] с шагом 1;&lt;br /&gt;
*	размерность векторов [20 : 400] с шагом 20.&lt;br /&gt;
На графике 1 приведено время работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramTime.jpg|мини|upright=3|centre|framecentre|1|Рис. 7 Время работы программы в зависимости от числа процессоров и размерности задачи]]&lt;br /&gt;
На графике 2 приведена производительность работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramPerf.jpg|мини|upright=3|centre|framecentre|2|Рис. 8 Производительность программы в зависимости от количество процессоров и размерности задачи]]&lt;br /&gt;
На графике 3 приведена эффективность распараллеливания работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramParEffi.jpg|мини|upright=3|centre|framecentre|3|Рис. 9 Эффективность распараллеливания алгоритма]]&lt;br /&gt;
Оценим значения масштабируемости данной реализации:&lt;br /&gt;
Общей оценкой масштабируемости по числу процессов будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по числу процессов по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По числу процессоров: -0.009265. С увеличением числа процессоров наблюдается слабое снижение эффективности работы параллельной реализации алгоритма.&lt;br /&gt;
Общей оценкой масштабируемости по размеру решаемой задачи будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по размеру решаемой задачи по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По размеру задачи: 0.00002555. При увеличении размерности задачи эффективность алгоритма очень медленно возрастает.&lt;br /&gt;
Общей оценкой масштабируемости будем называть средний размер вклада каждого элемента рассматриваемой области значений в общую оценку по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По двум направлениям: 0.002079.&lt;br /&gt;
[https://bitbucket.org/d_2007_90/gram-schmidt-process/src Реализация алгоритма]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18221</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18221"/>
		<updated>2016-11-18T17:20:28Z</updated>

		<summary type="html">&lt;p&gt;DVIN: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась собственная параллельная реализация алгоритма, написанная на языке C++ с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Версия MPI - intel opemmpi/1.8.4-icc&lt;br /&gt;
&lt;br /&gt;
Модель используемого CPU - Intel Xeon X5570 2.93GHz&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проведём еще одно исследование исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта для меньшего числа процессоров. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:10] с шагом 1;&lt;br /&gt;
*	размерность векторов [20 : 400] с шагом 20.&lt;br /&gt;
На графике 1 приведено время работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramTime.jpg|мини|upright=3|centre|framecentre|1]]&lt;br /&gt;
На графике 2 приведена производительность работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramPerf.jpg|мини|upright=3|centre|framecentre|2]]&lt;br /&gt;
На графике 3 приведена эффективность распараллеливания работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramParEffi.jpg|мини|upright=3|centre|framecentre|3]]&lt;br /&gt;
Оценим значения масштабируемости данной реализации:&lt;br /&gt;
Общей оценкой масштабируемости по числу процессов будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по числу процессов по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По числу процессоров: -0.009265. С увеличением числа процессоров наблюдается слабое снижение эффективности работы параллельной реализации алгоритма.&lt;br /&gt;
Общей оценкой масштабируемости по размеру решаемой задачи будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по размеру решаемой задачи по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По размеру задачи: 0.00002555. При увеличении размерности задачи эффективность алгоритма очень медленно возрастает.&lt;br /&gt;
Общей оценкой масштабируемости будем называть средний размер вклада каждого элемента рассматриваемой области значений в общую оценку по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По двум направлениям: 0.002079.&lt;br /&gt;
[https://bitbucket.org/d_2007_90/gram-schmidt-process/src Реализация алгоритма]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:DVIN&amp;diff=18219</id>
		<title>Обсуждение участника:DVIN</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:DVIN&amp;diff=18219"/>
		<updated>2016-11-18T17:18:59Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Статья Участник:DVIN/Ортогонализация Грамма-Шмидта */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:DVIN/Ортогонализация Грамма-Шмидта]] ==&lt;br /&gt;
&lt;br /&gt;
* В разделе 1.3 определение вычислительного ядра можно опустить&lt;br /&gt;
**Исправлено&lt;br /&gt;
&lt;br /&gt;
=== По существу (будет добавляться по мере вычитывания) ===&lt;br /&gt;
&lt;br /&gt;
* Унифицируйте обозначения, а то у Вас в одном месте, например, для скалярного произведения угловые скобки, в другом - просто умножение через точку. И в случае неоднозначности конкретизируйте. Скажем, при нормализации норма там не всякая, а именно согласованная со скалярным произведением, это нужно указывать. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:10, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* Аккуратнее с терминами. Счётное множество вообще-то бесконечно, так что этот термин здесь неуместен. Вообще проверьте всё спеллером. &amp;quot;Линейно независимые&amp;quot; без пробела и т.п. - нехорошо. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:05, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* В Вашем представлении число векторов в системе необязательно равно размерности, но в стартовой вкладке вы даёте оценку при k=N, дайте лучше общую.  --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:04, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* В 1.8 - параллельно можно не только проекции, но и вычитания делать. Поправьте. На сегодня пока всё, завтра снова загляну. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:13, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:49, 16 ноября 2016 (MSK) &lt;br /&gt;
**Исправлено&lt;br /&gt;
* В разделе 2.4 не приведена использованная в экспериментах реализация алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:49, 16 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18218</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18218"/>
		<updated>2016-11-18T17:18:12Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась собственная параллельная реализация алгоритма, написанная на языке C++ с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Версия MPI - intel opemmpi/1.8.4-icc&lt;br /&gt;
&lt;br /&gt;
Модель используемого CPU - Intel Xeon X5570 2.93GHz&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проведём еще одно исследование исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта для меньшего числа процессоров. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:10] с шагом 1;&lt;br /&gt;
*	размерность векторов [20 : 400] с шагом 20.&lt;br /&gt;
На графике 1 приведено время работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramTime.jpg|мини|upright=3|centre|framecentre|1]]&lt;br /&gt;
На графике 2 приведена производительность работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramPerf.jpg|мини|upright=3|centre|framecentre|2]]&lt;br /&gt;
На графике 3 приведена эффективность распараллеливания работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramParEffi.jpg|мини|upright=3|centre|framecentre|3]]&lt;br /&gt;
Оценим значения масштабируемости данной реализации:&lt;br /&gt;
Общей оценкой масштабируемости по числу процессов будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по числу процессов по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По числу процессоров: -0.009265. С увеличением числа процессоров наблюдается слабое снижение эффективности работы параллельной реализации алгоритма.&lt;br /&gt;
Общей оценкой масштабируемости по размеру решаемой задачи будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по размеру решаемой задачи по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По размеру задачи: 0.00002555. При увеличении размерности задачи эффективность алгоритма очень медленно возрастает.&lt;br /&gt;
Общей оценкой масштабируемости будем называть средний размер вклада каждого элемента рассматриваемой области значений в общую оценку по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По двум направлениям: 0.002079.&lt;br /&gt;
[https://bitbucket.org/d_2007_90/gram-schmidt-process/src Реализация алгоритма]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18199</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18199"/>
		<updated>2016-11-18T16:11:18Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась собственная параллельная реализация алгоритма, написанная на языке C++ с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Версия MPI - intel opemmpi/1.8.4-icc&lt;br /&gt;
&lt;br /&gt;
Модель используемого CPU - Intel Xeon X5570 2.93GHz&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проведём еще одно исследование исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта для меньшего числа процессоров. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:10] с шагом 1;&lt;br /&gt;
*	размерность векторов [20 : 400] с шагом 20.&lt;br /&gt;
На графике 1 приведено время работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramTime.jpg|мини|upright=3|centre|framecentre|1]]&lt;br /&gt;
На графике 2 приведена производительность работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramPerf.jpg|мини|upright=3|centre|framecentre|2]]&lt;br /&gt;
На графике 3 приведена эффективность распараллеливания работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramParEffi.jpg|мини|upright=3|centre|framecentre|3]]&lt;br /&gt;
Оценим значения масштабируемости данной реализации:&lt;br /&gt;
Общей оценкой масштабируемости по числу процессов будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по числу процессов по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По числу процессоров: -0.009265. С увеличением числа процессоров наблюдается слабое снижение эффективности работы параллельной реализации алгоритма.&lt;br /&gt;
Общей оценкой масштабируемости по размеру решаемой задачи будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по размеру решаемой задачи по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По размеру задачи: 0.00002555. При увеличении размерности задачи эффективность алгоритма очень медленно возрастает.&lt;br /&gt;
Общей оценкой масштабируемости будем называть средний размер вклада каждого элемента рассматриваемой области значений в общую оценку по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По двум направлениям: 0.002079.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18196</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18196"/>
		<updated>2016-11-18T16:02:54Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Версия MPI - intel opemmpi/1.8.4-icc&lt;br /&gt;
&lt;br /&gt;
Модель используемого CPU - Intel Xeon X5570 2.93GHz&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проведём еще одно исследование исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта для меньшего числа процессоров. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:10] с шагом 1;&lt;br /&gt;
*	размерность векторов [20 : 400] с шагом 20.&lt;br /&gt;
На графике 1 приведено время работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramTime.jpg|мини|upright=3|centre|framecentre|1]]&lt;br /&gt;
На графике 2 приведена производительность работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramPerf.jpg|мини|upright=3|centre|framecentre|2]]&lt;br /&gt;
На графике 3 приведена эффективность распараллеливания работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramParEffi.jpg|мини|upright=3|centre|framecentre|3]]&lt;br /&gt;
Оценим значения масштабируемости данной реализации:&lt;br /&gt;
Общей оценкой масштабируемости по числу процессов будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по числу процессов по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По числу процессоров: -0.009265. С увеличением числа процессоров наблюдается слабое снижение эффективности работы параллельной реализации алгоритма.&lt;br /&gt;
Общей оценкой масштабируемости по размеру решаемой задачи будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по размеру решаемой задачи по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По размеру задачи: 0.00002555. При увеличении размерности задачи эффективность алгоритма очень медленно возрастает.&lt;br /&gt;
Общей оценкой масштабируемости будем называть средний размер вклада каждого элемента рассматриваемой области значений в общую оценку по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По двум направлениям: 0.002079.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18192</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=18192"/>
		<updated>2016-11-18T16:01:37Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
Версия MPI - intel opemmpi/1.8.4-icc&lt;br /&gt;
Модель используемого CPU - Intel Xeon X5570 2.93GHz&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проведём еще одно исследование исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта для меньшего числа процессоров. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:10] с шагом 1;&lt;br /&gt;
*	размерность векторов [20 : 400] с шагом 20.&lt;br /&gt;
На графике 1 приведено время работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramTime.jpg|мини|upright=3|centre|framecentre|1]]&lt;br /&gt;
На графике 2 приведена производительность работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramPerf.jpg|мини|upright=3|centre|framecentre|2]]&lt;br /&gt;
На графике 3 приведена эффективность распараллеливания работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramParEffi.jpg|мини|upright=3|centre|framecentre|3]]&lt;br /&gt;
Оценим значения масштабируемости данной реализации:&lt;br /&gt;
Общей оценкой масштабируемости по числу процессов будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по числу процессов по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По числу процессоров: -0.009265. С увеличением числа процессоров наблюдается слабое снижение эффективности работы параллельной реализации алгоритма.&lt;br /&gt;
Общей оценкой масштабируемости по размеру решаемой задачи будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по размеру решаемой задачи по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По размеру задачи: 0.00002555. При увеличении размерности задачи эффективность алгоритма очень медленно возрастает.&lt;br /&gt;
Общей оценкой масштабируемости будем называть средний размер вклада каждого элемента рассматриваемой области значений в общую оценку по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По двум направлениям: 0.002079.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17983</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17983"/>
		<updated>2016-11-17T18:22:56Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проведём еще одно исследование исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта для меньшего числа процессоров. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:10] с шагом 1;&lt;br /&gt;
*	размерность векторов [20 : 400] с шагом 20.&lt;br /&gt;
На графике 1 приведено время работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramTime.jpg|мини|upright=3|centre|framecentre|1]]&lt;br /&gt;
На графике 2 приведена производительность работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramPerf.jpg|мини|upright=3|centre|framecentre|2]]&lt;br /&gt;
На графике 3 приведена эффективность распараллеливания работы программы для разных значений размерности матрицы и числа процессоров.&lt;br /&gt;
[[File:GramParEffi.jpg|мини|upright=3|centre|framecentre|3]]&lt;br /&gt;
Оценим значения масштабируемости данной реализации:&lt;br /&gt;
Общей оценкой масштабируемости по числу процессов будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по числу процессов по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По числу процессоров: -0.009265. С увеличением числа процессоров наблюдается слабое снижение эффективности работы параллельной реализации алгоритма.&lt;br /&gt;
Общей оценкой масштабируемости по размеру решаемой задачи будем называть среднее значение вклада каждого элемента рассматриваемой области значений в общую оценку по размеру решаемой задачи по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По размеру задачи: 0.00002555. При увеличении размерности задачи эффективность алгоритма очень медленно возрастает.&lt;br /&gt;
Общей оценкой масштабируемости будем называть средний размер вклада каждого элемента рассматриваемой области значений в общую оценку по всем элементам рассматриваемой области параметров запуска.&lt;br /&gt;
* По двум направлениям: 0.002079.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17840</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17840"/>
		<updated>2016-11-17T00:21:12Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:GramTime.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
[[File:GramPerf.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
[[File:GramParEffi.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17839</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17839"/>
		<updated>2016-11-17T00:20:08Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:GramImpEffi.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
[[File:GramParEffi.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
[[File:GramPerf.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
[[File:GramTime.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17605</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17605"/>
		<updated>2016-11-16T11:30:45Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17600</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17600"/>
		<updated>2016-11-16T11:24:12Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
Так как алгоритм не поддается полному распараллеливанию, то при увеличении числа процессоров не происходит значительного ускорения. Это связано с тем, что параллельно можно вычислить лишь &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Но после этого все процессоры должны синхронизоваться и дождаться когда получат следующий вектор &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17514</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17514"/>
		<updated>2016-11-16T00:45:42Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размерность векторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17513</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17513"/>
		<updated>2016-11-16T00:11:19Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации процесса ортогонализации Грама-Шмидта. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [10:100] с шагом 10;&lt;br /&gt;
*	размер верторов [50 : 500] с шагом 50.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке приведен график времени работы алгоритма в зависимости от числа процессов и размерности векторов.&lt;br /&gt;
[[File:gram-schmidt.jpg|мини|upright=3|centre|framecentre|frame]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17491</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=17491"/>
		<updated>2016-11-15T21:32:52Z</updated>

		<summary type="html">&lt;p&gt;DVIN: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:DVIN&amp;diff=16351</id>
		<title>Обсуждение участника:DVIN</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:DVIN&amp;diff=16351"/>
		<updated>2016-11-10T22:57:13Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Статья Участник:DVIN/Ортогонализация Грамма-Шмидта */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:DVIN/Ортогонализация Грамма-Шмидта]] ==&lt;br /&gt;
&lt;br /&gt;
* В разделе 1.3 определение вычислительного ядра можно опустить&lt;br /&gt;
**Исправлено&lt;br /&gt;
&lt;br /&gt;
=== По существу (будет добавляться по мере вычитывания) ===&lt;br /&gt;
&lt;br /&gt;
* Унифицируйте обозначения, а то у Вас в одном месте, например, для скалярного произведения угловые скобки, в другом - просто умножение через точку. И в случае неоднозначности конкретизируйте. Скажем, при нормализации норма там не всякая, а именно согласованная со скалярным произведением, это нужно указывать. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:10, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* Аккуратнее с терминами. Счётное множество вообще-то бесконечно, так что этот термин здесь неуместен. Вообще проверьте всё спеллером. &amp;quot;Линейно независимые&amp;quot; без пробела и т.п. - нехорошо. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:05, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* В Вашем представлении число векторов в системе необязательно равно размерности, но в стартовой вкладке вы даёте оценку при k=N, дайте лучше общую.  --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:04, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;br /&gt;
* В 1.8 - параллельно можно не только проекции, но и вычитания делать. Поправьте. На сегодня пока всё, завтра снова загляну. --[[Участник:Frolov|Фролов А.В.]] ([[Обсуждение участника:Frolov|обсуждение]]) 14:13, 8 ноября 2016 (MSK)&lt;br /&gt;
**Исправлено&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16281</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16281"/>
		<updated>2016-11-09T17:21:56Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16280</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16280"/>
		<updated>2016-11-09T17:19:47Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной). Причем берется норма согласованная со скалярным произведением &amp;lt;math&amp;gt;\| x \| = \sqrt{\langle x, x \rangle}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16279</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16279"/>
		<updated>2016-11-09T17:15:53Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Реализация для MATLAB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейно независимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16278</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16278"/>
		<updated>2016-11-09T17:15:22Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Реализация для MATLAB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацию Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16277</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16277"/>
		<updated>2016-11-09T17:05:12Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16276</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16276"/>
		<updated>2016-11-09T17:04:40Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt;=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16275</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16275"/>
		<updated>2016-11-09T17:04:24Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt;=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16274</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16274"/>
		<updated>2016-11-09T17:02:40Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16273</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16273"/>
		<updated>2016-11-09T17:01:43Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;. Кроме того можно параллельно производить вычитание соответствующего &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16272</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=16272"/>
		<updated>2016-11-09T16:57:00Z</updated>

		<summary type="html">&lt;p&gt;DVIN: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|ASA}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(Nk)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=14365</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=14365"/>
		<updated>2016-10-28T12:08:34Z</updated>

		<summary type="html">&lt;p&gt;DVIN: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=14155</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=14155"/>
		<updated>2016-10-27T11:05:52Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=11882</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=11882"/>
		<updated>2016-10-15T20:41:27Z</updated>

		<summary type="html">&lt;p&gt;DVIN: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грама-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро&#039;&#039;&#039; (computational kernel) алгоритма - это часть алгоритма, на которую приходится основное время его работы.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=11767</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=11767"/>
		<updated>2016-10-15T20:23:19Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грамма-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро&#039;&#039;&#039; (computational kernel) алгоритма - это часть алгоритма, на которую приходится основное время его работы.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: &lt;br /&gt;
&lt;br /&gt;
результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=11766</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=11766"/>
		<updated>2016-10-15T20:22:54Z</updated>

		<summary type="html">&lt;p&gt;DVIN: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грамма-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро&#039;&#039;&#039; (computational kernel) алгоритма - это часть алгоритма, на которую приходится основное время его работы.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=11617</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=11617"/>
		<updated>2016-10-15T20:03:04Z</updated>

		<summary type="html">&lt;p&gt;DVIN: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грамма-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро&#039;&#039;&#039; (computational kernel) алгоритма - это часть алгоритма, на которую приходится основное время его работы.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=11597</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=11597"/>
		<updated>2016-10-15T19:57:59Z</updated>

		<summary type="html">&lt;p&gt;DVIN: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Ортогонализация Грамма-Шмидта&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:DVIN|Инжелевская Дарья Валерьевна]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Создатели алгоритма Эрхард Шмидт и Йорген Педерсен Грам.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Эрхард Шмидт&#039;&#039;&#039; (14 января 1876 — 6 декабря 1959) — немецкий математик, с 1917 года профессор Берлинского университета. В 1946—58 первый директор Института математики АН ГДР. Основные труды по теории функций, интегральным уравнениям, функциональному анализу. Определил и изучил геометрически гильбертово пространство, используя аналогии с геометрией Евклида. Занимался квадратичными формами. Известен оператор Гильберта-Шмидта и процесс Грама ― Шмидта.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Йорген Педерсен Грам&#039;&#039;&#039; (27 июня 1850 - 29 апреля 1916) датский математик, родился в герцогстве Шлезвиг, Дания и умер в Копенгагене, Дания. Основные его работы &amp;quot;On series expansions determined by the methods of least squares&amp;quot;, &amp;quot;Investigations of the number of primes less than a given number&amp;quot;. Математический метод, который носит его имя, процесс Грама-Шмидта, впервые был опубликован в 1883. Теорема Грама и Определитель Грама также назван в его честь.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b}_{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e}_{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}}&amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\; \mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
==== Классический процесс Грама — Шмидта ====&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим оператор проекции следующим образом: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = {\langle \mathbf{a}, \mathbf{b} \rangle \over \langle \mathbf{b}, \mathbf{b}\rangle} \mathbf{b} ,&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — скалярное произведение векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Скалярное произведение для двух векторов  &amp;lt;math&amp;gt;\mathbf{ a= [a_1, a_2, ...,a_k]}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{ b= [b_1, b_2, ..., b_k]}&amp;lt;/math&amp;gt;  в &#039;&#039;&#039;&#039;&#039;k&#039;&#039;&#039;&#039;&#039;-мерном действительном пространстве определяется как:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^k a_ib_i=a_1b_1+a_2b_2+\cdots+ a_kb_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; коллинеарно вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ортогональность векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
{\begin{array}{lclr}&lt;br /&gt;
{\mathbf  {b}}_{1}&amp;amp;=&amp;amp;{\mathbf  {a}}_{1}&amp;amp;(1)\\&lt;br /&gt;
{\mathbf  {b}}_{2}&amp;amp;=&amp;amp;{\mathbf  {a}}_{2}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{2}&amp;amp;(2)\\&lt;br /&gt;
{\mathbf  {b}}_{3}&amp;amp;=&amp;amp;{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{3}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{3}&amp;amp;(3)\\&lt;br /&gt;
{\mathbf  {b}}_{4}&amp;amp;=&amp;amp;{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{1}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{2}}}\,{\mathbf  {a}}_{4}-{\mathbf  {proj}}_{{{\mathbf  {b}}_{3}}}\,{\mathbf  {a}}_{4}&amp;amp;(4)\\&lt;br /&gt;
&amp;amp;\vdots &amp;amp;&amp;amp;\\{\mathbf  {b}}_{N}&amp;amp;=&amp;amp;{\mathbf  {a}}_{N}-\displaystyle \sum _{{j=1}}^{{N-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{N}&amp;amp;(N)&lt;br /&gt;
\end{array}}&lt;br /&gt;
 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен нормированный вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
===== Доказательство =====&lt;br /&gt;
Докажем ортогональность векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для этого вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt;, подставив в него формулу (2). Мы получим ноль. Равенство нулю скалярного произведения векторов означает, что эти векторы ортогональны. Затем вычислим скалярное произведение &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_3 \rangle&amp;lt;/math&amp;gt;, используя результат для &amp;lt;math&amp;gt;\langle \mathbf{b}_1, \mathbf{b}_2 \rangle&amp;lt;/math&amp;gt; и формулу (3). Мы снова получим ноль, то есть векторы &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогональны. Общее доказательство выполняется методом математической индукции.&lt;br /&gt;
&lt;br /&gt;
===== Геометрическая интерпретация — вариант 1 =====&lt;br /&gt;
[[Файл:Gram-Schmidt-step2.svg|right|frame|Рис. 1. Второй шаг процесса Грама — Шмидта]]&lt;br /&gt;
Рассмотрим формулу (2) — второй шаг алгоритма.&lt;br /&gt;
Её геометрическое представление изображено на рис. 1:&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_2&amp;lt;/math&amp;gt;, то есть [[перпендикуляр]]а, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Этот перпендикуляр — вычисляемый в формуле (2) вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — перемещение полученного на шаге 2 вектора &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (2).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; ортогонален вектору &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_2&amp;lt;/math&amp;gt; проецируется на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим формулу (3) — третий шаг алгоритма — в следующем варианте:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lcr}&lt;br /&gt;
\mathbf{b}_3 = \mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3+\mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3) &amp;amp; &amp;amp; (6) \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её геометрическое представление изображено на рис. 2:&lt;br /&gt;
[[Файл:Gram-schmidt-step3base1.png|center|frame|Рис. 2. Третий шаг процесса Грама — Шмидта]]&lt;br /&gt;
&lt;br /&gt;
1 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2 — получение проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3 — вычисление суммы &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3&amp;lt;/math&amp;gt;, то есть проекции вектора &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Эта плоскость закрашена на рисунке серым цветом;&lt;br /&gt;
&lt;br /&gt;
4 — вычисление &amp;lt;math&amp;gt;\mathbf{a}_3-(\mathbf{proj}_{\mathbf{b}_1}\mathbf{a}_3 + \mathbf{proj}_{\mathbf{b}_2}\mathbf{a}_3)&amp;lt;/math&amp;gt;, то есть перпендикуляра, которым выполняется проецирование конца &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;. Этот перпендикуляр — вычисляемый в формуле (6) вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
5 — перемещение полученного &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; в начало координат. Это перемещение сделано на рисунке лишь для наглядности. Оно не является математическим действием и поэтому не отражается в формуле (6).&lt;br /&gt;
&lt;br /&gt;
На рисунке видно, что вектор &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; ортогонален векторам &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;\mathbf{b}_3&amp;lt;/math&amp;gt; является перпендикуляром, по которому &amp;lt;math&amp;gt;\mathbf{a}_3&amp;lt;/math&amp;gt; проецируется на плоскость, образуемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в процессе Грама — Шмидта для вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; выполняется проецирование &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; ортогонально на [[гиперплоскость]]?, формируемую векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; затем вычисляется как разность между &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; и его проекцией. То есть &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; — это перпендикуляр? от конца &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; к гиперплоскости?, формируемой векторами &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{j-1}&amp;lt;/math&amp;gt;. Поэтому &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; ортогонален векторам, образующим эту гиперплоскость?.&lt;br /&gt;
&lt;br /&gt;
===== Численная неустойчивость =====&lt;br /&gt;
При вычислении на ЭВМ по формулам (1) — (5) векторы &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_{N-1}&amp;lt;/math&amp;gt; часто не точно ортогональны из-за [[Ошибка квантования|ошибок округления]]. Из-за потери ортогональности в процессе вычислений классический процесс Грама — Шмидта называют [[Численная устойчивость|численно неустойчивым]].&lt;br /&gt;
&lt;br /&gt;
==== Модифицированный процесс Грама — Шмидта ====&lt;br /&gt;
Процесс Грама — Шмидта может быть сделан более вычислительно устойчивым путём небольшой модификации. Вместо вычисления &amp;lt;math&amp;gt;\mathbf{b}_j&amp;lt;/math&amp;gt; как: &amp;lt;math&amp;gt; \mathbf{b}_j = \mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_j - \ldots - \mathbf{proj}_{\mathbf{b}_{j-1}}\,\mathbf{a}_j  \; (7) &amp;lt;/math&amp;gt; этот вектор вычисляется следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt; \begin{array}{lclr}&lt;br /&gt;
\mathbf{a}_j^{(1)} &amp;amp; = &amp;amp;\mathbf{a}_j - \mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_j &amp;amp; (8) \\&lt;br /&gt;
\mathbf{a}_j^{(2)} &amp;amp; = &amp;amp;\mathbf{a}_j^{(1)} - \mathbf{proj}_{\mathbf{b}_2} \, \mathbf{a}_j^{(1)} &amp;amp; (9) \\&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{a}_j^{(j-2)} &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-3)} - \mathbf{proj}_{\mathbf{b}_{j-2}} \, \mathbf{a}_j^{(j-3)} &amp;amp; (10) \\&lt;br /&gt;
\mathbf{b}_j &amp;amp; = &amp;amp; \mathbf{a}_j^{(j-2)} - \mathbf{proj}_{\mathbf{b}_{j-1}} \, \mathbf{a}_j^{(j-2)} &amp;amp; (11)&lt;br /&gt;
\end{array} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро&#039;&#039;&#039; (computational kernel) алгоритма - это часть алгоритма, на которую приходится основное время его работы.&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода ортогонализации Грамма-Шмидта можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычислений проекций : &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Данный алгоритм использует в качестве составных частей другие алгоритмы. В дальнейшем имеет смысл описывать алгоритм не в максимально детализированном виде (т.е. на уровне арифметических операций), а давать только его макроструктуру, то есть описывает структуру и состав макроопераций. Типичной макрооперацией, часто встречающиеся в алгоритме является оператор проекции векторов. Как записано и в описании ядра алгоритма, основную часть метода ортогонализации Грамма-Шмидта составляют множественные (всего их &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt;) вычисления оператора проекции.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Следующий алгоритм реализует нормализацию Грамма-Шмидта. Векторы &amp;lt;math&amp;gt;v_1,...,v_k&amp;lt;/math&amp;gt; заменяются набором ортонормированных векторов, которые имеют ту же линейную оболочку.&lt;br /&gt;
[[File:Gram-Schmidt ortho.png|none|thumb]]&lt;br /&gt;
&lt;br /&gt;
Вычислительная сложность этого &amp;lt;math&amp;gt;2Nk^2&amp;lt;/math&amp;gt; операции с плавающей точкой, где N - размерность векторов.&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\mathbf  {b}_{1}=\mathbf  {a}_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Далее для всех векторов &amp;lt;math&amp;gt;\mathbf  {b}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;i=2 ... N&amp;lt;/math&amp;gt; производим вычисление по следующей формуле:&lt;br /&gt;
&amp;lt;math&amp;gt;{\mathbf  {b}}_{i}={\mathbf  {a}}_{i}-\displaystyle \sum _{{j=1}}^{{i-1}}{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
В ней на каждом шаге &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; по очереди вычисляются все &amp;lt;math&amp;gt;{\mathbf  {proj}}_{{{\mathbf  {b}}_{j}}}\,{\mathbf  {a}}_{i}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;j=1 ... i-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример реализации на Python. Функция работает для произвольного количества векторов любой размерности. При этом если количество векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt; больше их размерности или они линейно зависимы то функция возвращает максимально возможное число линейно независимых векторов &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_n&amp;lt;/math&amp;gt;, а остальные векторы &amp;lt;math&amp;gt;\mathbf{b}_{n+1},\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; нулевые.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def GramSchmidt(*a):&lt;br /&gt;
    k=len(a[0])&lt;br /&gt;
    N=len(a);&lt;br /&gt;
    b = [[0] * k for i in range(N)]&lt;br /&gt;
    b[0]=a[0]&lt;br /&gt;
    for i in range(1,N):&lt;br /&gt;
        sum=a[i]&lt;br /&gt;
        for j in range(0,i):&lt;br /&gt;
            scolar_ab=0&lt;br /&gt;
            scolar_bb=0&lt;br /&gt;
            proj=[i for i in range(k)]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                scolar_ab+=b[j][n]*a[i][n]&lt;br /&gt;
                scolar_bb+=b[j][n]*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                proj[n]=(scolar_ab/scolar_bb)*b[j][n]&lt;br /&gt;
            for n in range(k):&lt;br /&gt;
                sum[n]-=proj[n]&lt;br /&gt;
        b[i]=sum&lt;br /&gt;
    return b;&lt;br /&gt;
&lt;br /&gt;
l1=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l2=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
l3=[random.randrange(0,10) for i in range(3)]&lt;br /&gt;
print(l1,l2,l3)&lt;br /&gt;
print(GramSchmidt(l1,l2,l3))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортогонального набора векторов в последовательном варианте требуется:&lt;br /&gt;
&lt;br /&gt;
При k=N:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3N-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3N^2 (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При k≠N&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{N(N-1)(3k-1)}{2}&amp;lt;/math&amp;gt; сложений (вычитаний),&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{3Nk (N-1)}{2}&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам с кубической сложностью.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Опишем граф алгоритма как аналитически, так и в виде рисунка.&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, расположенных в целочисленных узлах двух областей.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i} = {\langle \mathbf{a_i}, \mathbf{b_j} \rangle \over \langle \mathbf{b_j}, \mathbf{b_j}\rangle} \mathbf{b_j} ,&amp;lt;/math&amp;gt; . Естественно введённые координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;:&lt;br /&gt;
элементы входных данных, а именно &amp;lt;math&amp;gt;a_i&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt;: &lt;br /&gt;
результат срабатывания операции, соответствующей вершине из второй группы, с координатой j.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двухмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b&amp;lt;/math&amp;gt;. &lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
&lt;br /&gt;
i — меняется в диапазоне от 2 до N, принимая все целочисленные значения;&lt;br /&gt;
&lt;br /&gt;
j — меняется в диапазоне от 1 до i-1, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
a:&lt;br /&gt;
&lt;br /&gt;
j=1 - входные данные &amp;lt;math&amp;gt;a_j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
j&amp;gt;1 - результат срабатывания операции, соответствующей вершине из второй группы, с координатой j-1&lt;br /&gt;
&lt;br /&gt;
b: результат срабатывания операции, соответствующей вершине из первой группы, с координатой j&lt;br /&gt;
[[Файл:picture00001.jpg|мини|upright=2|centre|frame|Рис. 5. Граф алгоритма с отображением входных и выходных данных. Proj - вычисление оператора проекции, F - операция a-b, In - входные данные, Out - результаты.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, в отличие от последовательного, вычисления  &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt;  можно выполнять параллельно. То есть после каждого вычисления &amp;lt;math&amp;gt;b_j&amp;lt;/math&amp;gt; можно запускать параллельное вычисление &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b_j}}\,\mathbf{a_i}&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;i=j+1..N&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для ортогонализации в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов в каждом из которых будет выполнятся,&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; операторов проекций (в каждом из ярусов линейное количество проекций, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;N - 1&amp;lt;/math&amp;gt; сложений (в каждом из ярусов линейное количество сложений, в зависимости от яруса — от &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте (количество ярусов в ЯПФ ) ЯПФ, таким образом, ортогонализация Грамма-Шмидта относится к алгоритмам со сложностью O(N). &lt;br /&gt;
&lt;br /&gt;
При классификации по ширине (максимальное количество вершин в ярусе) ЯПФ его сложность будет O(N^2).&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множества линейно независимых векторов  &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ a_i= [a^i_1, a^i_2, ..., a^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* вектора &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; линейно независимы, поэтому &amp;lt;math&amp;gt;k \geqslant N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt;, каждый из которых описывается &amp;lt;math&amp;gt;\mathbf{ b_i= [b^i_1, b^i_2, ..., b^i_k]}&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;Nk&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение кубической к квадратичной).&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, также линейна.&lt;br /&gt;
&lt;br /&gt;
Алгоритм почти полностью детерминирован — единственность результата выполнения гарантирована, однако возможно накопление ошибок округления при использовании классического процесса Грама-Шмидта. При этом модифицированный алгоритм дает более хороший результат.&lt;br /&gt;
&lt;br /&gt;
Алгоритм является численно неустойчивым — ошибки округления могут привести к неортогональности полученных векторов.&lt;br /&gt;
&lt;br /&gt;
Процесс Грама — Шмидта может применяться также к бесконечной последовательности линейно независимых векторов.&lt;br /&gt;
&lt;br /&gt;
Кроме того, процесс Грама — Шмидта может применяться к линейно зависимым векторам. В этом случае он выдаёт &amp;lt;math&amp;gt;\mathbf{0}&amp;lt;/math&amp;gt; (нулевой вектор) на шаге &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\mathbf{a}_j&amp;lt;/math&amp;gt; является линейной комбинацией векторов &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_{j-1}&amp;lt;/math&amp;gt;. Если это может случиться, то для сохранения ортогональности выходных векторов и для предотвращения деления на ноль при ортонормировании алгоритм должен делать проверку на нулевые векторы и отбрасывать их. Количество векторов, выдаваемых алгоритмом, будет равно размерности подпространства, порождённого векторами (т.е. количеству линейно независимых векторов, которые можно выделить среди исходных векторов).&lt;br /&gt;
&lt;br /&gt;
Процесс Грама ― Шмидта может быть истолкован как разложение невырожденной квадратной матрицы в произведение ортогональной (или унитарной матрицы в случае эрмитова пространства) и верхнетреугольной матрицы с положительными диагональными элементами ― QR-разложение, что есть частный случай разложения Ивасавы.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Примеры библиотек, содержащих реализации алгоритма ортогонализации Грама-Шмидта:&lt;br /&gt;
# [http://numerics.mathdotnet.com/Matrix.html C#] &lt;br /&gt;
# [http://www.mathworks.com/help/symbolic/mupad_ref/linalg-orthog.html?searchHighlight=orthogonalization Matlab]&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/Orthogonalize.html Wolfram]&lt;br /&gt;
# [http://www.nag.co.uk/numeric/Fl/manual/pdf/F05/f05aaf.pdf NAG Fortran]&lt;br /&gt;
&lt;br /&gt;
====Реализация для пакета Mathematica====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Mathematica, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в фигурных скобках последней строки. Количество векторов и их координат могут быть произвольными. В данном случае для примера взяты векторы {-2,1,0}, {-2,0,1}, {-0.5,-1,1}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;mathematica&#039;&amp;gt;&lt;br /&gt;
Projection[v1_, v2_] := (v1.v2*v2)/v2.v2&lt;br /&gt;
MultipleProjection[v1_, vecs_] := Plus @@ (Projection[v1, #1] &amp;amp;) /@ vecs&lt;br /&gt;
GramSchmidt[mat_] := Fold[Join[#1, {#2 - MultipleProjection[#2, #1]}] &amp;amp;, {}, mat]&lt;br /&gt;
GramSchmidt[{{-2, 1, 0}, {-2, 0, 1}, {-0.5, -1, 1}}]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для Maxima====&lt;br /&gt;
Данный скрипт, предназначенный для пакета Maxima, проводит процесс ортогонализации Грама ― Шмидта над векторами, заданными в квадратных скобках. Количество векторов и их координат могут быть произвольными. &lt;br /&gt;
&lt;br /&gt;
В данном случае для примера взяты векторы [-2,1,0], [-2,0,1], [-0.5,-1,1].&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tsql&amp;quot;&amp;gt;&lt;br /&gt;
load(eigen);&lt;br /&gt;
x: matrix ([-2,1,0],[-2,0,1],[-0.5,-1,1]);&lt;br /&gt;
y: gramschmidt(x);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Реализация для MATLAB====&lt;br /&gt;
В MATLAB существует встроенная функция [Q,R]=qr(A) которая осуществляет ортогонализацияю Грамма-Шмидта столбцов матрицы А. При этом столбцы матрицы предполагаются линейнонезависимыми.&lt;br /&gt;
 &lt;br /&gt;
[Q, R] = qr(A) возвращает матрицы Q с ортонормированными столбцами и обратимую верхнетреугольную матрицу R,  так что  A=Q*R&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Беклемишев Д. В. Курс аналитической геометрии и линейной алгебры. — М.: Наука.&lt;br /&gt;
* Гельфанд И. М. Лекции по линейной алгебре. — 5-е. — М.: Добросвет, МЦНМО, 1998. — 319 с. — ISBN 5-7913-0015-8.&lt;br /&gt;
*Ильин В. А., Позняк Э. Г.  Линейная алгебра. 6-е изд. — М.: Физматлит, 2010. — 280 с. — ISBN 978-5-9221-0481-4.&lt;br /&gt;
*Халмош П. Конечномерные векторные пространства = Finite-Dimensional Vector Spaces. — М.: Физматгиз, 1963. — 263 с.&lt;br /&gt;
*Фаддеев Д. К. Лекции по алгебре. — 5-е. — СПб.: Лань, 2007. — 416 с.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* https://ru.wikipedia.org/wiki/Процесс_Грама_―_Шмидта &#039;&#039;Процесс Грама ― Шмидта&#039;&#039;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=5666</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=5666"/>
		<updated>2016-10-12T10:26:24Z</updated>

		<summary type="html">&lt;p&gt;DVIN: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; Ортогонализация Грамма-Шмидта &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
=== Математическое описание алгоритма===&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== -Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== -Локальность данных и вычислений ===&lt;br /&gt;
=== -Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== -Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== -Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=5663</id>
		<title>Участник:DVIN/Ортогонализация Грамма-Шмидта</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN/%D0%9E%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%A8%D0%BC%D0%B8%D0%B4%D1%82%D0%B0&amp;diff=5663"/>
		<updated>2016-10-12T10:22:55Z</updated>

		<summary type="html">&lt;p&gt;DVIN: Новая страница: «&amp;#039;&amp;#039;&amp;#039; Ортогонализация Грамма-Шмидта &amp;#039;&amp;#039;&amp;#039;  == Свойства и структура алгоритмов == === Общее описани…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; Ортогонализация Грамма-Шмидта &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN&amp;diff=5660</id>
		<title>Участник:DVIN</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN&amp;diff=5660"/>
		<updated>2016-10-12T10:18:55Z</updated>

		<summary type="html">&lt;p&gt;DVIN: Полностью удалено содержимое страницы&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN&amp;diff=4025</id>
		<title>Участник:DVIN</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN&amp;diff=4025"/>
		<updated>2016-09-13T22:18:03Z</updated>

		<summary type="html">&lt;p&gt;DVIN: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; Ортогонализация Грамма-Шмидта &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN&amp;diff=4024</id>
		<title>Участник:DVIN</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:DVIN&amp;diff=4024"/>
		<updated>2016-09-13T21:57:35Z</updated>

		<summary type="html">&lt;p&gt;DVIN: Новая страница: «&amp;#039;&amp;#039;&amp;#039; Ортогонализация Грамма-Шмидта &amp;#039;&amp;#039;&amp;#039;  == Свойства и структура алгоритмов == === Общее описани…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; Ортогонализация Грамма-Шмидта &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Процесс Грама-Шмидта — это один из алгоритмов, в которых на основе счётного множества линейно независимых векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{N}}&amp;lt;/math&amp;gt; строится множество ортогональных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{1},\;\ldots ,\;\mathbf {b} _{N}} &amp;lt;/math&amp;gt; или ортонормированных векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{1},\;\ldots ,\;\mathbf {e} _{N}} &amp;lt;/math&amp;gt;, причём так, что каждый вектор &amp;lt;math&amp;gt;{\displaystyle \mathbf {b} _{j}} &amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;{\displaystyle \mathbf {e} _{j}} &amp;lt;/math&amp;gt; может быть выражен линейной комбинацией векторов &amp;lt;math&amp;gt;{\displaystyle \mathbf {a} _{1},\;\ldots ,\;\mathbf {a} _{j}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть имеются линейно независимые векторы &amp;lt;math&amp;gt;\mathbf{a}_1,\;\ldots,\;\mathbf{a}_N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Определим [[Оператор_(математика)|оператор]] [[Проектор (алгебра)|проекции]] следующим образом:&lt;br /&gt;
: &amp;lt;math&amp;gt;\mathbf{proj}_{\mathbf{b}}\,\mathbf{a} = &lt;br /&gt;
{\langle \mathbf{a}, \mathbf{b} \rangle&lt;br /&gt;
\over&lt;br /&gt;
\langle \mathbf{b}, \mathbf{b}\rangle}&lt;br /&gt;
\mathbf{b} ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\langle \mathbf{a}, \mathbf{b} \rangle&amp;lt;/math&amp;gt; — [[скалярное произведение]] векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;. Этот оператор проецирует вектор &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; [[Коллинеарность|коллинеарно]] вектору &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Ортогональность]] векторов &amp;lt;math&amp;gt;\mathbf{a}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{b}&amp;lt;/math&amp;gt; достигается на шаге (2).&lt;br /&gt;
&lt;br /&gt;
Классический процесс Грама — Шмидта выполняется следующим образом:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{lclr}&lt;br /&gt;
\mathbf{b}_1 &amp;amp; = &amp;amp; \mathbf{a}_1 &amp;amp; (1) \\&lt;br /&gt;
\mathbf{b}_2 &amp;amp; = &amp;amp; \mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_1 &amp;amp; (2) \\&lt;br /&gt;
\mathbf{b}_3 &amp;amp; = &amp;amp; \mathbf{a}_3-\mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_1-\mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_2 &amp;amp; (3) \\&lt;br /&gt;
\mathbf{b}_4 &amp;amp; = &amp;amp; \mathbf{a}_4-\mathbf{proj}_{\mathbf{b}_1}\,\mathbf{a}_1-\mathbf{proj}_{\mathbf{b}_2}\,\mathbf{a}_2-\mathbf{proj}_{\mathbf{b}_3}\,\mathbf{a}_3 &amp;amp; (4) \\&lt;br /&gt;
&amp;amp; \vdots &amp;amp; &amp;amp; \\&lt;br /&gt;
\mathbf{b}_N &amp;amp; = &amp;amp; \mathbf{a}_N-\displaystyle\sum_{j=1}^{N-1}\mathbf{proj}_{\mathbf{b}_j}\,\mathbf{a}_N &amp;amp; (N)&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На основе каждого вектора &amp;lt;math&amp;gt;\mathbf{b}_j \;(j = 1 \ldots N)&amp;lt;/math&amp;gt; может быть получен [[Норма вектора|нормированный]] вектор: &amp;lt;math&amp;gt;\mathbf{e}_j = {\mathbf{b}_j\over \| \mathbf{b}_j \|}&amp;lt;/math&amp;gt; (у нормированного вектора направление будет таким же, как у исходного, а длина — единичной).&lt;br /&gt;
&lt;br /&gt;
Результаты процесса Грама — Шмидта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; — система ортогональных векторов либо&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — система ортонормированных векторов.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;\mathbf{b}_1,\;\ldots,\;\mathbf{b}_N&amp;lt;/math&amp;gt; носит название ортогонализации Грама — Шмидта, а &amp;lt;math&amp;gt;\mathbf{e}_1,\;\ldots,\;\mathbf{e}_N&amp;lt;/math&amp;gt; — ортонормализации Грама — Шмидта.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>DVIN</name></author>
	</entry>
</feed>