<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=100241&amp;view=findpost&amp;p=759610</guid>
        <pubDate>Sun, 26 Jun 2005 12:35:08 +0000</pubDate>
        <title>Численные методы</title>
        <link>https://forum.sources.ru/index.php?showtopic=100241&amp;view=findpost&amp;p=759610</link>
        <description><![CDATA[Romtek: <span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Вычисление приближённого значения функций с помощью ряда Тейлора (Разложение функций в степенные ряды)</span></strong> (применяется также для нахождения пределов вообще)</span><br>
<br>
К примеру, <em class='tag-i'>sin = x -(x<sup class='tag-sup'>3</sup>/3&#33;)+(x<sup class='tag-sup'>5</sup>/5&#33;)- ... </em><br>
<hr>Здесь описано как вычислять <strong class='tag-b'>Sin, Cos, ArcTg, Exp</strong>. Другие функции пишутся аналогично.<br>
Значение функции вычисляется в процедуре <strong class='tag-b'>FunctionValue</strong>. Только подставьте нужное название функции.<hr><br>
<br>
Для того, чтобы вычислить <span class="tag-color tag-color-named" data-value="green" style="color: green">приближённое значение по формуле</span>, мы должны взять бесконечно большое число, чтобы приблизиться к истинному значению функции. Т.е. при <em class='tag-i'>n</em>-&gt;infinity (бесконечность), получаем истинное значение функции в данной точке.<br>
На практике мы этого не станем делать, так как в Паскале имеются типы с ограниченным размером, такие как: <em class='tag-i'>Real, Single, Double, Extended</em>. Что же теперь делать?<br>
<br>
Введём понятие <em class='tag-i'><strong class='tag-b'>точность вычисления</strong></em> и назовём эту переменную <em class='tag-i'>eps</em> (epsilon). Точность вычисления может быть разная: 0.05, 0.001 и намного большая, 10<sup class='tag-sup'>-8</sup>. В большинстве случаев хватает точности 3 знака после нуля, поэтому возьмём eps=0.001, или в краткой форме записи для Паскаля, 1e-3, что означает 1*10<sup class='tag-sup'>-3</sup>. Типа <em class='tag-i'>Single </em>для этой точности вполне хватит, на нём и остановимся.<br>
Если истинное значение функции в заданной точке равно, допустим, <span class="tag-color tag-color-named" data-value="blue" style="color: blue">1.232</span><span class="tag-color tag-color-named" data-value="purple" style="color: purple">8</span>, а вычисленное значение равно <span class="tag-color tag-color-named" data-value="blue" style="color: blue">1.232</span><span class="tag-color tag-color-named" data-value="purple" style="color: purple">3</span>, то при нашей точности вычисления разница по модулю между ними составляет 0.0005&lt;eps, то есть ответ нас устраивает.<br>
<br>
<strong class='tag-b'>Для вычисления бесконечного ряда нужно применить цикл</strong>, в котором мы каждый раз будем проверять, насколько точно вычислено требуемое значение X, то есть проверим:|<em class='tag-i'>Xnew - Xold</em>| &lt; <em class='tag-i'>eps</em> ?<br>
где <em class='tag-i'>Xnew</em> - это новое вычисленное значение,<br>
<em class='tag-i'>Xold</em> - предыдущее вычисленное значение<br>
Как только в ходе вычисления внутри цикла мы выясним, что достигнута требуемая точность (eps), выходим из него. Дальше вычислять уже нет необходимости.<br>
<br>
Далее. Как вычислять эти значения? Смотрим на общую формулу:<br>
<em class='tag-i'>sin (x) = Sum [(-1)<sup class='tag-sup'>n</sup> * x<sup class='tag-sup'>2n+1</sup> / (2n+1)&#33;]</em> , где <em class='tag-i'>n</em>-&gt;infinity.<br>
Из чего состоит данная формула?<br>
Из вычисления степени числа (функция <em class='tag-i'>Power</em>), факториала числа (функция <em class='tag-i'>Factorial</em>) и вычисления знака (функция <em class='tag-i'>Sign</em>).<br>
Для повторения вычисления этих функций смотрите прикреплённые вверху ссылки.<br>
<br>
Теперь надо собрать все эти функции в одном выражении, которое будет вычисляться в отдельной функции.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;{ вычисление значения элемента с индексом [I]i[/I] ряда Тейлора для синуса}</div><div class="code_line">function Sine (x: single; i: integer): single;</div><div class="code_line">var k: integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;K := 2 * i + 1;</div><div class="code_line">&nbsp;&nbsp;Sine := ( Sign (i) * Power (x, k) / factorial (k) );</div><div class="code_line">end;</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
Что осталось? Объединить всё написанное в одной функции вычисления приближённого значения <em class='tag-i'>FunctionValue</em>.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function FunctionValue (x: single): single;</div></ol></div></div></div></div>На входе задаётся точка (число), в которой нужно вычислить значение функции.<br>
<br>
А теперь программа:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">const eps: single = 1e-3; { Epsilon - необходимая точность, 1*10^(-3) }</div><div class="code_line">&nbsp;</div><div class="code_line">function Factorial (N: word): single; { N! }</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f: single;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Factorial := 1.0;</div><div class="code_line">&nbsp;&nbsp;if n = 0 then exit;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;f := 1.0;</div><div class="code_line">&nbsp;&nbsp;for n := 1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;f := f * n;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Factorial := f;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Sign (p: integer): single; { (-1)^p }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; if Not Odd(P) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; Sign := 1</div><div class="code_line">&nbsp;&nbsp; &nbsp; else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; Sign := -1;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Power (base: single; N: integer): single; { степень N по основанию base }</div><div class="code_line">var k: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;P: single;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; P := 1.0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; for k := 1 to N do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; P := P * base;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; Power := P;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{--------------------------------------------------------------------}</div><div class="code_line">&nbsp;</div><div class="code_line">function Sine (x: single; i: integer): single;</div><div class="code_line">var k: integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;K := 2 * i + 1;</div><div class="code_line">&nbsp;&nbsp;Sine := ( Sign (i) * Power (x, k) / factorial (k) );</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function CoSine (x: single; i: integer): single;</div><div class="code_line">var k: integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;K := 2 * i;</div><div class="code_line">&nbsp;&nbsp;CoSine := ( Sign (i) * Power (x, k) / factorial (k) );</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function ArcTg (x: single; i: integer): single;</div><div class="code_line">var k: integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;K := 2 * i + 1;</div><div class="code_line">&nbsp;&nbsp;ArcTg := ( Sign (i) * Power (x, k) / k );</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Exp (x: single; i: integer): single;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Exp := Power (x, i) / factorial (i);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{--------------------------------------------------------------------}</div><div class="code_line">&nbsp;</div><div class="code_line">function FunctionValue (x: single): single;</div><div class="code_line">var sum,old: single;</div><div class="code_line">&nbsp;&nbsp; &nbsp;index: integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; if x &#60;= 0.0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FunctionValue := 0.0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; index := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; sum := 0.0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; repeat { повторять }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; old := sum; { old - прежнее вычисленное значение функции }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum := sum + ArcTg (x, index); &nbsp; { Sin, Cos, Exp }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index := index + 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; until abs (sum - old) &#60; eps; { пока не достигнута необходимая точность }</div><div class="code_line">&nbsp;&nbsp; &nbsp; FunctionValue := sum</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; writeln ( &#39;ArcTg (x) =&#39;, FunctionValue ( 1.0 / sqrt (3.0) ) : 8 : 3 ); &nbsp;{ ArcTg }</div><div class="code_line">{ &nbsp; &nbsp; writeln ( &#39;Cosinus (x) =&#39;, FunctionValue ( pi / 6.0 ) : 8 : 3 ); &nbsp;{ CoSine }</div><div class="code_line">&nbsp;&nbsp; &nbsp; readln;</div><div class="code_line">end.</div></ol></div></div></div></div>]]></description>
        <author>Romtek</author>
        <category>Pascal: Математика</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=100241&amp;view=findpost&amp;p=751240</guid>
        <pubDate>Thu, 16 Jun 2005 21:36:31 +0000</pubDate>
        <title>Численные методы</title>
        <link>https://forum.sources.ru/index.php?showtopic=100241&amp;view=findpost&amp;p=751240</link>
        <description><![CDATA[Romtek: <span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Методы решения дифференциальных уравнений.</span></strong></span><br>
<br>
  Данная статья посвящена численным методам решения дифференциальных уравнений.<br>
Мы будем рассматривать методы решения одного обыкновенного дифференциального<br>
уравнения первого порядка с одним начальным условием:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;y&#39; = f(x,y) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (1)</div><div class="code_line">&nbsp;&nbsp; &nbsp;y(x[0]) = y[0] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(2)</div></ol></div></div></div></div><br>
<br>
  Методы, которые здесь рассматриваются, легко обобщаются для системы уравнений<br>
первого порядка. А уравнения высших порядков можно свести к системе уравнений<br>
первого порядка.<br>
<br>
  <strong class='tag-b'>В основном существуют два широких класса методов:</strong><ul class="tag-list"><li> Одноступенчатые методы, в которых используется только информация о самой<br>
   кривой в одной точке и не производятся итерации. Один из методов - решение с<br>
   помощью рядов Тейлора, но на практике он не слишком удобен для использования.<br>
   Практически удобные методы этого класса - методы <span class="tag-color tag-color-named" data-value="orange" style="color: orange">Рунге-Кутта</span>. Эти методы<br>
   прямые (без итераций), но требуют многократных повторных вычислений функции.<br>
   При использовании данных методов трудно оценивать допускаемую ошибку.</li><li> Многоступенчатые методы, в которых следующую точку кривой можно найти, не<br>
   производя так много повторных вычислений, но для достижения достаточной<br>
   точности требуются итерации. Большинство методов этого класса называются<br>
   методами прогноза и коррекции (метод <span class="tag-color tag-color-named" data-value="orange" style="color: orange">Адамса-Бошфора</span>). некоторые трудности,<br>
   связанные с использованием итерационной процедуры и с использованием<br>
   нескольких начальных точек уравновешиваются тем фактом, что оценку ошибки<br>
   при использовании этого метода легко получить в качестве побочного продукта<br>
   вычислений.</li></ul><br>
  Как и во многих других случаях, эти два класса методов придется сочетать<br>
разумным образом, учитывая их достоинства и недостатки.<br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>	1. Методы Рунге-Кутта.</strong></span><br>
<br>
  Методы Рунге-Кутта обладают следующими отличительными свойствами:<ul class="tag-list"><li> Эти методы одноступенчатые: чтобы найти <em class='tag-i'>y[m+1]</em>, нужна информация только о<br>
   предыдущей точке <em class='tag-i'>x[m],y[m]</em>.</li><li> Они согласуются с рядом Тейлора вплоть до членов порядка <em class='tag-i'>h^p</em>,<br>
   где <em class='tag-i'>p</em> - различна для разных методов и называется порядком метода.</li><li> Они не требуют вычисления производных от <em class='tag-i'>f(x,y)</em>, а требуют только вычисления<br>
   самой функции.</li></ul><br>
  Именно благодаря <em class='tag-i'>3)</em> эти методы удобны для практических вычислений, однако для<br>
вычисления одной последующей точки решения нам придется вычислять <em class='tag-i'>f(x,y)</em><br>
несколько раз при различных x и y.<br>
<br>
<strong class='tag-b'>1.1. Метод Эйлера.</strong><br>
<br>
  Этот метод, один из самых старых и широко известных, описывается формулой:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;y[m+1] = y[m] + h*f(x[m],y[m]). &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (3)</div></ol></div></div></div></div><br>
<br>
  Найденное по формуле (3) решение согласуется с разложением в ряд Тейлора<br>
вплоть до членов порядка h, т.е. данный метод является методом Рунге-Кутта<br>
первого порядка.<br>
  Этот метод имеет довольно большую ошибку приближения, кроме того, он очень<br>
часто оказывается неустойчивым - изначально малая ошибка (происходящая от<br>
приближения, округления или исходных данных) увеличивается с ростом x.<br>
  Для вычисления <em class='tag-i'>y[m+1]</em> метод Эйлера использует наклон касательной только в<br>
точке <em class='tag-i'>x[m],y[m]</em>. Этот метод можно усовершенствовать множеством различных<br>
способов. Рассмотрим два из них.<br>
<br>
<strong class='tag-b'>1.2. Исправленный метод Эйлера.</strong><br>
<br>
  В исправленном методе Эйлера мы находим средний tg угла наклона касательной<br>
для двух точек: <em class='tag-i'>[I]x[m],y[m]</em> и <em class='tag-i'>x[m+1],y[m]+h*y&#39;[m]</em>[/I]. Соотношения, описывающие<br>
данный метод, имеют вид:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;y[m+1] = y[m] + h*F(x[m],y[m],h) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(4)</div><div class="code_line">&nbsp;&nbsp; &nbsp;F(x[m],y[m],h) = ( y&#39;[m] + f(x[m]+h, y[m]+h*y&#39;[m]) )/2 &nbsp; &nbsp; &nbsp;(5)</div><div class="code_line">&nbsp;&nbsp; &nbsp;y&#39;[m] = f(x[m],y[m]) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(6)</div></ol></div></div></div></div><br>
<br>
  Исправленный метод Эйлера согласуется с разложением в ряд Тейлора вплоть до<br>
членов степени <em class='tag-i'>h^2</em>, являясь, т.о. методом Рунге-Кутта второго порядка.<br>
<br>
<strong class='tag-b'>1.3. Модифицированный метод Эйлера.</strong><br>
<br>
  В данном методе мы находим tg угла наклона касательной в точке:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;x = x[m] + h/2; &nbsp; &nbsp; y = y[m] + (h/2)*y&#39;[m]</div></ol></div></div></div></div><br>
<br>
Соотношения, описывающие модифицированный метод Эйлера имеют вид:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;y[m+1] = y[m] + h*F(x[m],y[m],h) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(7)</div><div class="code_line">&nbsp;&nbsp; &nbsp;F(x[m],y[m],h) = f( x[m]+h/2, y[m]+(h/2)*y&#39;[m] ) &nbsp; &nbsp; &nbsp; &nbsp;(8)</div><div class="code_line">&nbsp;&nbsp; &nbsp;y&#39;[m] = f(x[m],y[m]) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(9)</div></ol></div></div></div></div><br>
<br>
  Модифицированный метод Эйлера также согласуется с разложением в ряд Тейлора<br>
вплоть до членов степени <em class='tag-i'>h^2</em>, и также является методом Рунге-Кутта второго<br>
порядка.<br>
<br>
<strong class='tag-b'>1.4. Метод Рунге-Кутта четвертого порядка.</strong><br>
<br>
  Данный метод является одним из самых употребительных методов интегрирования<br>
дифференциальных уравнений. Этот метод применяется настолько широко, что в<br>
литературе его просто называют &quot;методом Рунге-Кутта&quot; без всяких указаний на его<br>
тип или порядок. Этот классический метод описывается системой следующих пяти<br>
соотношений:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;y[m+1] = y[m] + h*(k[1] + 2*k[2] + 2*k[3] + k[4])/6 &nbsp; &nbsp; (10)</div><div class="code_line">&nbsp;&nbsp; &nbsp;k[1] = f(x[m], y[m]) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(11)</div><div class="code_line">&nbsp;&nbsp; &nbsp;k[2] = f(x[m]+h/2, y[m]+h*k[1]/2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (12)</div><div class="code_line">&nbsp;&nbsp; &nbsp;k[3] = f(x[m]+h/2, y[m]+h*k[2]/2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (13)</div><div class="code_line">&nbsp;&nbsp; &nbsp;k[4] = f(x[m]+h, y[m]+h*k[3]) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (14)</div></ol></div></div></div></div><br>
<br>
  Ошибка приближения для этого метода равна <em class='tag-i'>e[t]=k*h^5</em>. Заметим, что при<br>
использовании этого метода функцию необходимо вычислять четыре раза.<br>
<br>
  Один из серьезных недостатков методов Рунге-Кутта состоит в отсутствии<br>
простых способов оценки их ошибки.<br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>	2. Методы прогноза и коррекции.</strong></span><br>
<br>
  Отличительной чертой методов Рунге-Кутта является то, что при вычислении<br>
следующей точки <em class='tag-i'>(x[m+1],y[m+1])</em> используется информация только об одной<br>
предыдущей точке <em class='tag-i'>(x[m],y[m])</em>, но не нескольких. Кроме того, для методов<br>
Рунге-Кутта отсутствует достаточно простые способы оценки ошибки, что приводит<br>
к необходимости рассмотрения некоторых дополнительных методов решения ДУ.<br>
  Отличительное свойство этих методов состоит в том, что с их помощью нельзя<br>
начать решение уравнения т.к. в них необходимо использовать информацию о<br>
предыдущих точках решения. Чтобы начать решение, имея только одну точку,<br>
определяемую начальными условиями, или для того, чтобы изменить шаг <em class='tag-i'>(h)</em>,<br>
необходим метод типа Рунге-Кутта. Поэтому приходится использовать разумное<br>
сочетание этих двух методов.<br>
  Методы, которые мы рассмотрим, известны под общим названием методов прогно-<br>
за и корректировки. Как ясно из названия вначале &quot;предсказывается&quot; значение<br>
<em class='tag-i'>y[m+1]</em>, а затем используется тот или иной метод его &quot;корректировки&quot;.<br>
  Среди множества возможных формул прогноза и коррекции выберем по одному<br>
примеру, применимому ко многим практическим задачам.<br>
<br>
<strong class='tag-b'>2.1. Метод Адамса-Бошфора.</strong><br>
<br>
  Для прогноза используем формулу второго порядка<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;y^(0)_[m+1] = y[m-1] + 2*h*f(x[m],y[m]) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (15)</div></ol></div></div></div></div><br>
<br>
где (0) - означает исходное приближение y[m+1], т.е. предсказанное значение.<br>
Непосредственно из написанной формулы следует, что с ее помощью нельзя вычис-<br>
лить <em class='tag-i'>y[1]</em>, т.к. для его вычисления потребовалась бы точка, расположенная перед<br>
начальной точкой <em class='tag-i'>y[0]</em>. Чтобы начать решение с помошью метода прогноза и коррек-<br>
ции, для нахождения <em class='tag-i'>y[1]</em> необходимо использовать метод типа Рунге-Кутта.<br>
  Для коррекции возьмем формулу, похожую на исправленный метод Эйлера (4)-(6):<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;y^(i)_[m+1] = y[m] + h(f(x[m],y[m])+f(x[m+1],y^(i-1)_[m+1]))/2 &nbsp;(16)</div></ol></div></div></div></div><br>
<br>
для i=1,2,3, ...<br>
  Итерационный процесс прекращается, когда<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;| y^(i+1)_[m+1] - y^(i)_[m+1] | &#60; Eps &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (17)</div></ol></div></div></div></div><br>
<br>
для некоторого <em class='tag-i'>Eps&gt;0</em>.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Labinskiy Nikolay aka e-moe (c) 2005&#39;);</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;See you later on forum.sources.ru ;)&#39;);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">{$E+,N+,X+}</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;eps = 0.00001;</div><div class="code_line">&nbsp;&nbsp;x0 &nbsp;= 3;</div><div class="code_line">&nbsp;&nbsp;y0 &nbsp;= 3;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TFunc = function(x,y: extended): extended;</div><div class="code_line">&nbsp;</div><div class="code_line">function func(x,y: extended): extended; far;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;func := y*cos(x) - 2*sin(2*x);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Euler(f: TFunc; x0_,x_end,y0_: extended; n: word): extended;</div><div class="code_line">{ где x0_ и y0_ &nbsp;- начальное условие</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x_end - точка, в которой необходимо вычислить результат</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;n - количество шагов для вычисления результата }</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i &nbsp; : word; &nbsp; &nbsp; &nbsp;{ счетчик цикла }</div><div class="code_line">&nbsp;&nbsp;x,h : extended; &nbsp;{ текущая точка и длина шага }</div><div class="code_line">&nbsp;&nbsp;res : extended; &nbsp;{ переменная для накопления конечного результата функции}</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;h:= (x_end - x0_)/n; { Находим длину шага }</div><div class="code_line">&nbsp;&nbsp;res:= y0_; { устанавливаем начальные значения}</div><div class="code_line">&nbsp;&nbsp;x:=x0_;</div><div class="code_line">&nbsp;&nbsp;for i:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin { вычисляем результат по методу Эйлера }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;res:=res+h*f(x,res);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x:=x+h; { переходим к следующей точке }</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Euler:=res; &nbsp;{ присваиваем конечный результат функции }</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Euler2(f: TFunc; x0_,x_end,y0_: extended; n: word): extended;</div><div class="code_line">{ где x0_ и y0_ &nbsp;- начальное условие</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x_end - точка, в которой необходимо вычислить результат</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;n - количество шагов для вычисления результата }</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i &nbsp; : word; &nbsp; &nbsp; &nbsp;{ счетчик цикла }</div><div class="code_line">&nbsp;&nbsp;x,h : extended; &nbsp;{ текущая точка и длина шага }</div><div class="code_line">&nbsp;&nbsp;res : extended; &nbsp;{ переменная для накопления конечного результата функции}</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;h:= (x_end - x0_)/n; { Находим длину шага }</div><div class="code_line">&nbsp;&nbsp;res:= y0_; { устанавливаем начальные значения}</div><div class="code_line">&nbsp;&nbsp;x:=x0_;</div><div class="code_line">&nbsp;&nbsp;for i:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin { вычисляем результат по исправленному методу Эйлера }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;res:=res+h*(f(x,res)+f(x+h,res+h*f(x,res)))/2;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x:=x+h; { переходим к следующей точке }</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Euler2:=res; { присваиваем конечный результат функции }</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Euler3(f: TFunc; x0_,x_end,y0_: extended; n: word): extended;</div><div class="code_line">{ где x0_ и y0_ &nbsp;- начальное условие</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x_end - точка, в которой необходимо вычислить результат</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;n - количество шагов для вычисления результата }</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i &nbsp; : word; &nbsp; &nbsp; &nbsp;{ счетчик цикла }</div><div class="code_line">&nbsp;&nbsp;x,h : extended; &nbsp;{ текущая точка и длина шага }</div><div class="code_line">&nbsp;&nbsp;res : extended; &nbsp;{ переменная для накопления конечного результата функции}</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;h:= (x_end - x0_)/n; { Находим длину шага }</div><div class="code_line">&nbsp;&nbsp;res:= y0_; { устанавливаем начальные значения}</div><div class="code_line">&nbsp;&nbsp;x:=x0_;</div><div class="code_line">&nbsp;&nbsp;for i:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin { вычисляем результат по модифицированному методу Эйлера }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;res:=res+h*f(x+h/2,res+(h/2)*f(x,res));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x:=x+h; { переходим к следующей точке }</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Euler3:=res; { присваиваем конечный результат функции }</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function RungeKutt(f: TFunc; x0_,x_end,y0_: extended; n: word): extended;</div><div class="code_line">{ где x0_ и y0_ &nbsp;- начальное условие</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x_end - точка, в которой необходимо вычислить результат</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;n - количество шагов для вычисления результата }</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i &nbsp; : word; &nbsp; &nbsp; &nbsp;{ счетчик цикла }</div><div class="code_line">&nbsp;&nbsp;x,h : extended; &nbsp;{ текущая точка и длина шага }</div><div class="code_line">&nbsp;&nbsp;res : extended; &nbsp;{ переменная для накопления конечного результата функции }</div><div class="code_line">&nbsp;&nbsp;k1,k2,k3,k4: extended; { вспомогательные переменные вычисления результата }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;h:= (x_end - x0_)/n; { Находим длину шага }</div><div class="code_line">&nbsp;&nbsp;res:= y0_; { устанавливаем начальные значения}</div><div class="code_line">&nbsp;&nbsp;x:=x0_;</div><div class="code_line">&nbsp;&nbsp;for i:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin { вычисляем результат по методу Рунге-Кутта 4го порядка }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;k1:=f(x,res);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;k2:=f(x+h/2,res+h*k1/2);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;k3:=f(x+h/2,res+h*k2/2);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;k4:=f(x+h,res+h*k3);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;res:=res+h*(k1+2*k2+2*k3+k4)/6;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x:=x+h; { переходим к следующей точке }</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;RungeKutt:=res; { присваиваем конечный результат функции }</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function AdmsBoshf(f: TFunc; x0_,x_end,y0_: extended; n: word): extended;</div><div class="code_line">{ где x0_ и y0_ &nbsp;- начальное условие</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x_end - точка, в которой необходимо вычислить результат</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;n - количество шагов для вычисления результата }</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i &nbsp; &nbsp; : word; &nbsp; &nbsp; &nbsp; &nbsp; { счетчик цикла }</div><div class="code_line">&nbsp;&nbsp;x,h &nbsp; : extended; &nbsp; &nbsp; { текущая точка и длина шага }</div><div class="code_line">&nbsp;&nbsp;y1,y2 : extended; &nbsp; &nbsp; { переменные для вычисления следующей точки }</div><div class="code_line">&nbsp;&nbsp;tmp &nbsp; : extended; &nbsp; &nbsp; { временная переменная для уточнения результата }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;h:= (x_end - x0_)/n; { Находим длину шага }</div><div class="code_line">&nbsp;&nbsp;x:=x0_; { устанавливаем текущую точку }</div><div class="code_line">&nbsp;&nbsp;y1:=y0_+h*f(x+h/2,y0_+(h/2)*f(x,y0_)); { находим начальное значение</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; модифицированным методом Эйлера }</div><div class="code_line">&nbsp;&nbsp;repeat { уточняем(корректируем) начальное значение }</div><div class="code_line">&nbsp;&nbsp; &nbsp;tmp:=y1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;y1:=y0_+h*(f(x,y0_)+f(x+h,y1))/2;</div><div class="code_line">&nbsp;&nbsp;until abs(y1-tmp) &#60; eps;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;x:=x+h; { переходим к следующей точке }</div><div class="code_line">&nbsp;&nbsp;y2:=y0_+2*h*f(x,y1); { прогнозируенм следующее значение }</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;repeat { уточнаяем наш прогноз }</div><div class="code_line">&nbsp;&nbsp; &nbsp;tmp:=y2;</div><div class="code_line">&nbsp;&nbsp; &nbsp;y2:=y1+h*(f(x,y1)+f(x+h,y2))/2;</div><div class="code_line">&nbsp;&nbsp;until abs(y2-tmp) &#60; eps;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;for i:=3 to n do { начинаем счет с 3 т.к. две точки уже найдены }</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x0_:=x; { переходим к следующей точке }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x:=x+h;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;y0_:=y1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;y1:=y2;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;y2:=y0_+2*h*f(x,y1); { прогнозируенм следующее значение }</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;repeat { уточнаяем наш прогноз }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;tmp:=y2;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;y2:=y1+h*(f(x,y1)+f(x+h,y2))/2;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;until abs(y2-tmp) &#60; eps;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;AdmsBoshf:=y2; { присваиваем конечный результат функции }</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;Численное решение дифференциальных уравнений:&#39;);</div><div class="code_line">&nbsp;&nbsp;writeln(#10,&#39; &nbsp; y&#39;&#39; = y*cos(x) - 2*sin(2*x); &nbsp; y(0)=3; &nbsp; x_end=&#39;,(5*x0+3.5):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(#10,&#39;Метод Эйлера:&#39;);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=5 000, result: &#39;,Euler(func,x0,5*x0+3.5,y0,5000):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=10 000, result: &#39;,Euler(func,x0,5*x0+3.5,y0,10000):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=25 000, result: &#39;,Euler(func,x0,5*x0+3.5,y0,25000):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(#10,&#39;Исправленный метод Эйлера:&#39;);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=50, result: &#39;,Euler2(func,x0,5*x0+3.5,y0,50):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=100, result: &#39;,Euler2(func,x0,5*x0+3.5,y0,100):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=250, result: &#39;,Euler2(func,x0,5*x0+3.5,y0,250):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(#10,&#39;Модифицированный метод Эйлера:&#39;);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=50, result: &#39;,Euler3(func,x0,5*x0+3.5,y0,50):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=100, result: &#39;,Euler3(func,x0,5*x0+3.5,y0,100):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=250, result: &#39;,Euler3(func,x0,5*x0+3.5,y0,250):5:5);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;writeln(#10,&#39;Метод Рунге-Кутта:&#39;);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=50, result: &#39;,RungeKutt(func,x0,5*x0+3.5,y0,50):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=100, result: &#39;,RungeKutt(func,x0,5*x0+3.5,y0,100):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=250, result: &#39;,RungeKutt(func,x0,5*x0+3.5,y0,250):5:5);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;write(#10,&#39;Press Enter to continue.&#39;);</div><div class="code_line">&nbsp;&nbsp;readln;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;writeln(#10,&#39;Метод Адамса-Бошфора:&#39;);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=50, result: &#39;,AdmsBoshf(func,x0,5*x0+3.5,y0,50):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=100, result: &#39;,AdmsBoshf(func,x0,5*x0+3.5,y0,100):5:5);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;n=250, result: &#39;,AdmsBoshf(func,x0,5*x0+3.5,y0,250):5:5);</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
Автор статьи: Labinskiy Nikolay aka <strong class='tag-b'>e-moe</strong> © 2005<br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray"><span class='tag-size' data-value='7' style='font-size:7pt;'>Это сообщение было перенесено сюда или объединено из темы &quot;Численное решение ДУ&quot;</span></span>]]></description>
        <author>Romtek</author>
        <category>Pascal: Математика</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=100241&amp;view=findpost&amp;p=670695</guid>
        <pubDate>Mon, 04 Apr 2005 20:38:08 +0000</pubDate>
        <title>Численные методы</title>
        <link>https://forum.sources.ru/index.php?showtopic=100241&amp;view=findpost&amp;p=670695</link>
        <description><![CDATA[e-moe: <div class='tag-align-center'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Численное решение систем линейных алгебраических уравнений</strong></span></span></div><br>
<br>
Данная статья посвящена <span class="tag-color tag-color-named" data-value="purple" style="color: purple">нахождению корней систем линейных алгебраических уравнений</span>. Методы численного решения таких систем подразделяются на два типа: <em class='tag-i'>прямые (конечные)</em> и <em class='tag-i'>итерационные (бесконечные)</em>. Оба типа полезны и удобны для практических вычислений и каждый из них имеет свои преимущества и недостатки.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'> 1. Метод исключений (метод Гаусса). </strong></span><br>
<br>
Данный метод является наиболее известным и широко применяемым.<br>
<br>
Рассмотрим систему из <strong class='tag-b'>n </strong>уравнений с <strong class='tag-b'>n </strong>неизвестными. Обозначим неизвестные через <em class='tag-i'>x[1], x[2], ... , x[n] </em>и запишем систему в следующем виде:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; a[1,1]*x[1] + a[1,2]*x[2] + ... + a[1,n]*x[n] = b[1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; a[2,1]*x[1] + a[2,2]*x[2] + ... + a[2,n]*x[n] = b[2]</div><div class="code_line">&nbsp;&nbsp; &nbsp; ....................................................</div><div class="code_line">&nbsp;&nbsp; &nbsp; a[n,1]*x[1] + a[n,2]*x[2] + ... + a[n,n]*x[n] = b[n]</div></ol></div></div></div></div><br>
<br>
Предполагается, что в силу расположения уравнений, <em class='tag-i'>a[i,i] &lt;&gt; 0</em>. Если это не так, то, меняя уравнения местами, добиваемся выполнения этого условия. Введем <strong class='tag-b'>n-1</strong> множителей:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; m[i] = a[i,1]/a[1,1] &nbsp; , где i = 2, 3, ... , n</div></ol></div></div></div></div><br>
<br>
и вычтем из каждого <strong class='tag-b'>i</strong>-го уравнения первое, умноженное на <strong class='tag-b'>m,</strong> обозначая<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; a&#39;[i,j] = a[i,j] - m[i]*a[1,j]</div><div class="code_line">&nbsp;&nbsp; &nbsp; b&#39;[i] = - m[i]*b[i]</div><div class="code_line">&nbsp;&nbsp; &nbsp; i = 2, 3, ... , n; &nbsp;j = 1, 2, ... , n.</div></ol></div></div></div></div><br>
<br>
Для всех уравнений, начиная со второго, получим:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; a[i,1] = 0 &nbsp; , где i = 2, 3, ... , n.</div></ol></div></div></div></div><br>
<br>
Преобразованная система уравнений запишется в следующем виде:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; a[1,1]*x[1] + a[1,2]*x[2] + ... + a[1,n]*x[n] = b[1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; + &nbsp; &nbsp; a&#39;[2,2]*x[2] + ... + a&#39;[2,n]*x[n] = b&#39;[2]</div><div class="code_line">&nbsp;&nbsp; &nbsp; ....................................................</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; + &nbsp; &nbsp; a&#39;[n,2]*x[2] + ... + a&#39;[n,n]*x[n] = b&#39;[n]</div></ol></div></div></div></div><br>
<br>
Продолжая таким же образом, исключаем <strong class='tag-b'>x[2]</strong> из последних <strong class='tag-b'>n-2</strong> уравнений, затем <strong class='tag-b'>x[3]</strong> из последних <strong class='tag-b'>n-3</strong> и т.д. На некотором <strong class='tag-b'>k</strong>-м этапе мы исключаем <strong class='tag-b'>x[k]</strong> с помощью множителей:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; m^(k-1)_[i] = a^(k-1)_[i,k]/a^(k-1)_[k,k] &nbsp; , i = k+1, ... , n,</div></ol></div></div></div></div><br>
<br>
не забывая, что a<sup class='tag-sup'>(k-1)</sup><sub class='tag-sub'>[k,k]</sub> &lt;&gt; 0.<br>
  Примечание, <strong class='tag-b'>^(k-1)</strong> обозначает на <strong class='tag-b'>k</strong>-1й итерации<br>
              <strong class='tag-b'>_[i,k]</strong> - индекс эл-та.<br>
  Тогда<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; a^(k)_[i,j] = a^(k-1)_[i,j] - m^(k-1)_[i]*a^(k-1)_[k,j]</div><div class="code_line">&nbsp;&nbsp; &nbsp; b^(k)_[i] = - m^(k-1)_[i]*b^(k-1)_[k]</div><div class="code_line">&nbsp;&nbsp; &nbsp; i = k+1, k+2, ... , n; &nbsp;j = k, k+1, ... , n.</div></ol></div></div></div></div><br>
<br>
Окончательно, треугольная система уравнений записывается:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; a[1,1]*x[1] + a[1,2]*x[2] + ... + a[1,n]*x[n] = b[1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a[2,2]*x[2] + ... + a[2,n]*x[n] = b[2]</div><div class="code_line">&nbsp;&nbsp; &nbsp; ....................................................</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a[n,n]*x[n] = b[n]</div></ol></div></div></div></div><br>
<br>
Обратная подстановка для нахождения значений неизвестных задается формулами:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; x[n] = b^(n-1)_[n] / a^(n-1)_[n,n]</div><div class="code_line">&nbsp;&nbsp; &nbsp; x[n-1] = (b^(n-2)_[n-1] - a^(n-2)_[n-1,n]*x[n]) / a^(n-2)_[n-1,n-1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; ...................................................................</div><div class="code_line">&nbsp;&nbsp; &nbsp; x[j] = ( b^(j-1)_[j] - a^(j-1)_[j,n]*x[n] - ... -</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- a^(j-1)_[j,j+1]*x[j+1] ) / a^(j-1)_[j,j]</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; j = n-2, n-3, ... , 1.</div></ol></div></div></div></div><br>
<br>
Перед началом процесса исключения очередного неизвестного может понадобиться переставить уравнения в системе, чтобы <span class='tag-u'>избежать деления на нуль</span>. Кроме этого, при перестановке уравнений необходимо добиваться того, чтобы<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; | a^(k-1)_[k,k] | &#62;= | a^(k-1)_[i,k] |</div></ol></div></div></div></div><br>
<br>
Поэтому перед началом процесса исключения очередного неизвестного необходимо переставить уравнения так, чтобы максимальный по модулю коэффициент при <strong class='tag-b'>x[k]</strong> попал на главную диагональ (<em class='tag-i'>данный способ решения часто называется <span class="tag-color tag-color-named" data-value="magenta" style="color: magenta"><strong class='tag-b'>методом главного элемента</strong></span></em>).<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>2. Итерационный метод Гаусса-Зейделя.</strong></span><br>
<br>
Данный метод <span class='tag-u'>отличается простотой и легкостью программирования</span>, малой ошибкой округления, но сходится при выполнении некоторых условий.<br>
<br>
Рассмотрим все ту же систему из <strong class='tag-b'>n </strong>уравнений с <strong class='tag-b'>n </strong>неизвестными. По прежнему полагаем, что <strong class='tag-b'>a[i,i] &lt;&gt;0</strong> для всех <strong class='tag-b'>i</strong>. Тогда <strong class='tag-b'>k</strong>-е приближение к решению будет задаваться формулой:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;x^(k)_[i] = ( b[i] - a[i,1]*x^(k)_[1] - ... - a[i,j-1]*x^(k)_[i-1] -</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- a[i,j+1]*x^(k-1)_[i+1] - a[i,n]*x^(k-1)_[n] ) / a[i,i]</div><div class="code_line">&nbsp;&nbsp;i = 1, 2, ... , n.</div></ol></div></div></div></div><br>
<br>
Как известно, любой итерационный процесс, как и настоящий мужик, должен имееть свой конец :)<br>
<br>
Поэтому вычисления нужно продолжать до тех пор, все x^(k)_[i] не станут достаточно близки к x<sup class='tag-sup'>(k-1)</sup><sub class='tag-sub'>[i]</sub>, т.е. пока для всех <strong class='tag-b'>i </strong>не будет выполнятся неравенство<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; max| x^(k)_[i] - x^(k-1)_[i] | &#60; Eps,</div></ol></div></div></div></div><br>
<br>
где <strong class='tag-b'>Eps </strong>некоторое положительное число, задающее точность вычислений.<br>
<br>
Итерационный метод <span class="tag-color tag-color-named" data-value="magenta" style="color: magenta"><strong class='tag-b'>Гаусса-Зейделя</strong></span> сходится, если <span class='tag-u'>удовлетворяется достаточное условие сходимости</span>: для всех <strong class='tag-b'>i </strong>модуль диагонального коэффициента должен быть не меньше суммы модулей остальных коэффициентов данной строки<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; | a[i,i] | &#62;= | a[i,1] | + | a[i,2] | + ... + | a[i,j-1] | +</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + | a[i,j+1] | + ... + | a[i,n] | ,</div></ol></div></div></div></div><br>
<br>
а хотя бы для одной строки это неравенство должно выполнятся строго<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; | a[i,i] | &#62; | a[i,1] | + | a[i,2] | + ... + | a[i,j-1] | +</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ | a[i,j+1] | + ... + | a[i,n] |.</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>3. Сравнение методов.</strong></span><br>
<br>
Метод исключений имеет то преимущество, что он конечен и теоретически, с его помощью можно решить любую невырожденную систему. Итерационный метод сходится только для специальных систем уравнений, однако когда итерационные методы сходятся, они, обычно, предпочтительнее:<br>
<ul class="tag-list"><li>Время вычислений пропорционально n<sup class='tag-sup'>2</sup> на итерацию, в то время как для метода исключений время пропорционально n<sup class='tag-sup'>3</sup>. Если для решения системы требуется меньше чем n итераций, то общие затраты машинного времени будут меньше.</li><li>Как правило, ошибки округления в итерационном методе меньше. Часто, это соображение может оказаться достаточно важным, что оправдывает дополнительные затраты машинного времени. Многие систему, возникающие на практике, имеют среди коэффициентов большое кол-во нулей. В этом случае итерационные методы, если они сходятся, в высшей степени предпочтительны т.к. в методе исключений получается треугольная система, которая в качестве коэффициентов нулей обычно не содержит.</li></ul><br>
А вот и исходник по теме:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Labinskiy Nikolay aka e-moe (c) 2005&#39;);</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;See you later on forum.sources.ru ;)&#39;);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">{$N+,G+,X+}</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;Comments: boolean = false; { нужно ли печатать пошаговые рез-ты расчета }</div><div class="code_line">&nbsp;&nbsp;Eps = 0.00001; &nbsp; &nbsp; &nbsp; &nbsp;{ Точность вычислений }</div><div class="code_line">&nbsp;&nbsp;n_max = 4; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Кол-во ур-й и неизвестных }</div><div class="code_line">&nbsp;&nbsp;const_AnB: array[1..n_max,1..n_max+1] of double =</div><div class="code_line">&nbsp;(( -8, &nbsp; 2, &nbsp;17, &nbsp;-5, -119.97),</div><div class="code_line">&nbsp;{ -8*X[1] + 2*X[2] + 17*X[3] - 5*X[4] = -119.97 &nbsp;и т.д. ... }</div><div class="code_line">&nbsp;&nbsp;( &nbsp;4, -22, &nbsp; 6, &nbsp; 5, &nbsp; 55.73),</div><div class="code_line">&nbsp;&nbsp;( 15, &nbsp; 3, &nbsp;-5, &nbsp;-5, &nbsp; 18.77),</div><div class="code_line">&nbsp;&nbsp;( -4, &nbsp;-4, &nbsp; 5, &nbsp;14, &nbsp;-79.42));</div><div class="code_line">{ Описание типов матрицы уравнеиний и массива найденных Х }</div><div class="code_line">Type TMatr = array[1..n_max,1..n_max+1] of double;</div><div class="code_line">Type TXMarr = array[1..n_max] of double;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure PrintX(const X: TXMarr; n: byte; cnt: word);</div><div class="code_line">{ Печатает найденные Х }</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;k, &nbsp; &nbsp; &nbsp; { Позиция заданного корня в массиве }</div><div class="code_line">&nbsp;&nbsp;i: byte; { Номер текущего корня для вывода }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if n = 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp;k:=low(X);</div><div class="code_line">&nbsp;&nbsp;if cnt = 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;write(&#39; N &nbsp; &nbsp; &nbsp; x1&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for i:=2 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;write(&#39; &nbsp; &nbsp; &nbsp; &nbsp; x&#39;,i);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;writeln;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;write(cnt:2);</div><div class="code_line">&nbsp;&nbsp;for i:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Write(&#39; &nbsp; &#39;,X[k]:3:5);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc(k);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;writeln;</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;При решении систем, с большим кол-вом неизвестных, возможно,</div><div class="code_line">&nbsp;&nbsp;придется переделать эту процедуру для корректного вывода</div><div class="code_line">&nbsp;&nbsp;всех решений.</div><div class="code_line">}</div><div class="code_line">end; { PrintX }</div><div class="code_line">&nbsp;</div><div class="code_line">procedure PrintMatr(var AnB: TMatr; n: byte);</div><div class="code_line">{ Печатает заданную матрицу }</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i,j: byte;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;for i:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for j:=1 to n+1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;write(AnB[i,j]:3:5,&#39; &nbsp; &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;writeln;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;writeln;</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;При решении систем, с большим кол-вом неизвестных, возможно,</div><div class="code_line">&nbsp;&nbsp;придется переделать эту процедуру для корректного вывода</div><div class="code_line">&nbsp;&nbsp;всех решений.</div><div class="code_line">}</div><div class="code_line">end; { PrintMatr }</div><div class="code_line">&nbsp;</div><div class="code_line">function Normalize(var AnB: TMatr; n: byte): byte;</div><div class="code_line">{</div><div class="code_line">&nbsp;Располагает на главной диагонали наибольшие элементы в столбцах</div><div class="code_line">&nbsp;Если один из них равен нулю,то систему решить не получится ...</div><div class="code_line">&nbsp;Возвращает 0 если систему заданными методами решить не получится,</div><div class="code_line">&nbsp;1 - с-му можно решить только методом Гаусса</div><div class="code_line">&nbsp;2 - с-му можно решать любым методом</div><div class="code_line">}</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;max: double; { Переменная для поиска макс. эл-та }</div><div class="code_line">&nbsp;&nbsp;imax: byte; &nbsp;{ Переменная для поиска макс. эл-та }</div><div class="code_line">&nbsp;&nbsp;tmp: double; { Переменная для обмена элементов }</div><div class="code_line">&nbsp;&nbsp;i,j: byte; &nbsp; { Счетчики циклов }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Normalize:=2;</div><div class="code_line">&nbsp;&nbsp;for j:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;max:=Abs(AnB[1,j]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;imax:=1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for i:=2 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if Abs(AnB[i,j]) &#62; max then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;max:=Abs(AnB[i,j]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;imax:=i;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if max &#60; Eps then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Normalize:=0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Writeln(&#39;Error: a[i,i]=0!&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if j &#60;&#62; imax then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for i:=1 to n+1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tmp:=AnB[j,i];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AnB[j,i]:=AnB[imax,i];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AnB[imax,i]:=tmp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;for i:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;tmp:=0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for j:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if i &#60;&#62; j then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tmp:=tmp+Abs(AnB[i,j]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if Abs(AnB[i,i]) &#60; tmp then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Normalize:=1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">end; { Normalize }</div><div class="code_line">&nbsp;</div><div class="code_line">procedure Metod1(const Matr; n: byte);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;k &nbsp; &nbsp;: byte;</div><div class="code_line">&nbsp;&nbsp;M_ &nbsp; : TMatr absolute Matr;</div><div class="code_line">&nbsp;&nbsp;AnB &nbsp;: TMatr;</div><div class="code_line">&nbsp;&nbsp;X,M &nbsp;: TXMarr;</div><div class="code_line">function Calc(k: byte): boolean;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i,j &nbsp;: byte;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Calc:= true;</div><div class="code_line">&nbsp;&nbsp;for i:=k+1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;M[i]:= AnB[i,k]/AnB[k,k];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if M[i] &#62; 1 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Calc:= false;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;for i:=k+1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;for j:=k to n+1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;AnB[i,j]:=AnB[i,j]-M[i]*AnB[k,j];</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;if Comments then</div><div class="code_line">&nbsp;&nbsp; &nbsp;PrintMatr(AnB,n);</div><div class="code_line">end; { Calc }</div><div class="code_line">function Summ(j: byte): double;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i : byte;</div><div class="code_line">&nbsp;&nbsp;res : double;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;res:=AnB[j,n+1];</div><div class="code_line">&nbsp;&nbsp;for i:=n downto j+1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp;res:=res - AnB[j,i]*X[i];</div><div class="code_line">&nbsp;&nbsp;Summ:=res;</div><div class="code_line">end; { Summ }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Метод Гаусса:&#39;);</div><div class="code_line">&nbsp;&nbsp;AnB:=M_;</div><div class="code_line">&nbsp;&nbsp;if Normalize(AnB,n) = 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;writeln(&#39;Error: Невозможно решить систему уравнений!&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;for k:=1 to n-1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp;if not Calc(k) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Writeln(&#39;Error: Невыполняется условие | a^(k-1)_[k,k] | &#62;= | a^(k-1)_[i,k] | !&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;X[n]:=AnB[n,n+1]/AnB[n,n];</div><div class="code_line">&nbsp;&nbsp;for k:=n-1 downto 1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp;X[k]:=Summ(k)/AnB[k,k];</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;PrintX(X,n,0);</div><div class="code_line">&nbsp;&nbsp;Writeln;</div><div class="code_line">end; { Metod1 }</div><div class="code_line">&nbsp;</div><div class="code_line">procedure Metod2(const Matr; n: byte);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;M_ &nbsp; : TMatr absolute Matr;</div><div class="code_line">&nbsp;&nbsp;AnB &nbsp;: TMatr;</div><div class="code_line">&nbsp;&nbsp;X &nbsp; &nbsp;: TXMarr;</div><div class="code_line">&nbsp;&nbsp;i,j: byte;</div><div class="code_line">&nbsp;&nbsp;tmp: double;</div><div class="code_line">&nbsp;&nbsp;delta: double;</div><div class="code_line">&nbsp;&nbsp;cnt: word;</div><div class="code_line">function Summ(i: byte): double;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;j: byte;</div><div class="code_line">&nbsp;&nbsp;res: double;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;res:=AnB[i,n+1];</div><div class="code_line">&nbsp;&nbsp;for j:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;if i &#60;&#62; j then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;res:=res-AnB[i,j]*X[j];</div><div class="code_line">&nbsp;&nbsp;Summ:=res;</div><div class="code_line">end; { Summ }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;Метод Гаусса-Зейделя:&#39;);</div><div class="code_line">&nbsp;&nbsp;AnB:=M_;</div><div class="code_line">&nbsp;&nbsp;For i:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp;X[i]:=0;</div><div class="code_line">&nbsp;&nbsp;if Normalize(AnB,n) &#60;&#62; 2 then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;writeln(&#39;Error: !&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;delta:=1;</div><div class="code_line">&nbsp;&nbsp;cnt:=0;</div><div class="code_line">&nbsp;&nbsp;while delta &#62; Eps do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if Comments then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;PrintX(X,n,cnt);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;delta:=0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for i:=1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tmp:=Summ(i)/AnB[i,i];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if delta &#60; Abs(tmp-X[i]) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;delta:=Abs(tmp-X[i]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;X[i]:=tmp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc(cnt);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;PrintX(X,n,cnt);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;Заданная точность вычислений достигнута на &#39;,cnt,&#39; шаге.&#39;);</div><div class="code_line">&nbsp;&nbsp;Writeln;</div><div class="code_line">end; { Metod2 }</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Writeln(#10,&#39;Численное решение систем линейных алгебраических уравнений:&#39;,#10);</div><div class="code_line">&nbsp;&nbsp;Metod1(const_AnB,n_max);</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Press Enter to continue&#39;);</div><div class="code_line">&nbsp;&nbsp;readln;</div><div class="code_line">&nbsp;&nbsp;Metod2(const_AnB,n_max);</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Press Enter if you wanna DOS ;)&#39;);</div><div class="code_line">&nbsp;&nbsp;readln;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray"><span class='tag-size' data-value='7' style='font-size:7pt;'>Это сообщение было перенесено сюда или объединено из темы &quot;Решение уравнений&quot;</span></span>]]></description>
        <author>e-moe</author>
        <category>Pascal: Математика</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=100241&amp;view=findpost&amp;p=665661</guid>
        <pubDate>Thu, 31 Mar 2005 11:59:35 +0000</pubDate>
        <title>Численные методы</title>
        <link>https://forum.sources.ru/index.php?showtopic=100241&amp;view=findpost&amp;p=665661</link>
        <description><![CDATA[Romtek: <span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'><span class='tag-size' data-value='11' style='font-size:11pt;'>Численное решение уравнений итерационными методами.</span></strong></span><br>
<br>
Автор:<br>
<pre>  DonNTU. <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=9927' target='_blank'>e-moe</a> aka Labinskiy Nikolay &copy; 2005</pre><br>
<br>
  Данная статья посвящена <span class="tag-color tag-color-named" data-value="purple" style="color: purple">нахождению корней уравнения</span><div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;F(x)=0, &nbsp; &nbsp;(1)</div></ol></div></div></div></div><br>
где функция <em class='tag-i'>F(x)</em> может быть алгебраической либо трансцендентной и должна удовлетворять условию дифференцируемости.<br>
Как правило, численное решение уравнений состоит из двух этапов:<br>
нахождение приближенного значения корня и его уточнение до заданной точности. Начальное приближение часто<br>
известно из физических соображений либо находится специальными методами, например, графически. Подробно будет<br>
рассмотрен второй этап решения уравнений: нахождение корня с заданной точностью различными итерационными методами.<br>
<ul class="tag-list"><li><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Метод последовательных приближений.</span><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function Metod1(f: TFunc; x0: double): double;</div></ol></div></div></div></div><br>
  В данном методе для удобства вычислений переходят от исходного уравнения (1) к уравнению<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;x=f(x). &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (2)</div></ol></div></div></div></div><br>
  Данный переход можно осуществить множеством способов, например, прибавить к обеим частям (1) <em class='tag-i'>x</em>.<br>
  Суть метода последовательных приближений состоит в том, что начальное приближение <em class='tag-i'>x[0]</em> подставляется в правую часть<br>
формулы (2) и вычисляется значение <em class='tag-i'>x[1]</em>. Затем полученное <em class='tag-i'>x[1]</em> снова подставляется в правую часть формулы (2)<br>
и вычисляется <em class='tag-i'>x[2]</em>, потом <em class='tag-i'>x[3]</em> и т.д. Рабочая формула метода последовательных приближений имеет вид<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;x[n]=f(x[n-1]). &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (3)</div></ol></div></div></div></div><br>
  Вычисления продолжаются до тех пор, пока не будет достигнута заданная точность <em class='tag-i'>Eps</em>, т.е<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;| x[n]-x[n-1] | &#60; Eps. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(4)</div></ol></div></div></div></div><br>
  Основной проблемой при работе с итерационными методами является <strong class='tag-b'>проблема сходимости</strong>. Достаточным условием сходимости метода последовательных приближений является выполнение условия<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;| f&#39;(x[n]) | &#60; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(5)</div></ol></div></div></div></div>для всех значений x[n].<br>
</li><li><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Усовершенствованный метод последовательных приближений.</span><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function Metod2(f: TFunc; x0: double): double;</div></ol></div></div></div></div><br>
  Формула данного итерационного метода имеет вид<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;x[n+1] = x[n] + A*( f(x[n]) - x[n] ), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (6)</div></ol></div></div></div></div>где A определяется по формулам<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;A = 1/(1 - f&#39;(s)) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (7)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;f&#39;(s) = ( f(x[n]) - x[n] )/( x[n] - x[n-1] ) &nbsp; &nbsp;(8)</div></ol></div></div></div></div>при этом на первом шаге <em class='tag-i'>x[1]</em> определяется простым методом последовательных приближений.<br>
</li><li><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Метод Ньютона-Рафсона, Бриге-Виетта.</span><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function Metod3(f: TFunc; x0: double): double;</div></ol></div></div></div></div><br>
  Небольшая дальнейшая модификация усовершенствованного метода последовательных приближений приводит к одному из<br>
наиболее известных численных методов решения уравнений - <span class="tag-color tag-color-named" data-value="magenta" style="color: magenta">методу Ньютона-Рафсона</span>. Формула метода для <em class='tag-i'>f(x)</em>, подчиняющегося соотношению (2), имеет вид<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;x[n+1] = (f(x[n])-x[n]*f&#39;(x[n]))/(1-f&#39;(x[n])), &nbsp;(9)</div></ol></div></div></div></div>при этом <em class='tag-i'>сходимость метода обеспечивается</em>, если:<ol class="tag-list" type="1"><li><em class='tag-i'>x[0]</em> выбрано достаточно близко к решению <em class='tag-i'>x = f(x)</em>;</li><li>Вторая производная <em class='tag-i'>f&#39;&#39;(x)</em> не становится слишком большой;</li><li>Производная <em class='tag-i'>f&#39;(x)</em> не слишком близка к 1.<br>
  Формула Ньютона-Рафсона для <em class='tag-i'>F(x)</em>, подчиняющегося соотношению (1), имеет вид<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;x[n+1] = x[n] - F(x[n])/F&#39;(x[n]), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (10)</div></ol></div></div></div></div></li></ul>при этом условия сходимости принимают вид:<ol class="tag-list" type="1"><li><em class='tag-i'>x[0]</em> выбрано достаточно близко к решению <em class='tag-i'>x = F(x)</em>;</li><li>Вторая производная<em class='tag-i'> f&#39;&#39;(x)</em> не становится слишком большой;</li><li>Производная <em class='tag-i'>f&#39;(x)</em> не слишком близка к 0.</li></ol><br>
  Применим метод Ньютона-Рафсона согласно формуле (10), при этом вычисление <em class='tag-i'>F(x)</em> будем осуществлять по <span class="tag-color tag-color-named" data-value="magenta" style="color: magenta">правилу Горнера</span><br>
<strong class='tag-b'>с использованием рекуррентных формул</strong>:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;b[m] = a[m]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;b[j] = a[j] + x[n]*b[j+1], j=m-1, ..., 0 &nbsp; &nbsp; &nbsp; &nbsp;(11)</div></ol></div></div></div></div><br>
  Таким образом находим <em class='tag-i'>F(x) = b[0]</em>.<br>
  F&#39;(x) представляет собой многочлен степени <em class='tag-i'>m-1</em>. Воспользовавшись для его вычисления теми же рекуррентными формулами, имеем:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;c[m] = b[m]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;c[j] = b[j] + x[n]*c[j+1], j=m-1, ..., 1 &nbsp; &nbsp; &nbsp; &nbsp;(12)</div></ol></div></div></div></div><br>
и соответственно <em class='tag-i'>F&#39;(x) = c[1]</em>.<br>
  Подставляя найденные значения<em class='tag-i'> F(x)</em> и <em class='tag-i'>F&#39;(x)</em> в формулу (10) для метода Ньютона-Рафсона, получаем<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;x[n+1] = x[n] - b[0]/c[1], &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(13)</div></ol></div></div></div></div><br>
где <em class='tag-i'>b[o]</em> и <em class='tag-i'>c[1]</em> вычислены по формулам (11) и (12).<br>
Тихо и незаметно мы пришли к <span class="tag-color tag-color-named" data-value="magenta" style="color: magenta">методу Бриге-Виетта</span> ;)</li></ol><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;DonNTU. e-moe aka Labinskiy Nikolay (c) 2005</div><div class="code_line">&nbsp;&nbsp;visit www.sources.ru</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">{$N+,G+,X+}</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;Eps = 0.00001; &nbsp; &nbsp; &nbsp; &nbsp;{ Точность вычислений }</div><div class="code_line">&nbsp;&nbsp;anMax = 3; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Степень полинома }</div><div class="code_line">&nbsp;&nbsp;{ Коэффициенты полинома F(x) = a[0]+a[1]*x+a[2]*x^2+ ... +a[n]*x^n }</div><div class="code_line">&nbsp;&nbsp;An: array[0..anMax] of double = (-5.372,1.2493,0.559,-0.13);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ a[0] &nbsp; a[1] &nbsp;a[2] &nbsp;a[3] }</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;{ Описание функции для передачи ее в кач-ве параметра функциям }</div><div class="code_line">&nbsp;&nbsp;TFunc = function(x: double; px: byte; d: shortint): double;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;x0,x1,x2: double; { Переменные для вычисления корней }</div><div class="code_line">&nbsp;</div><div class="code_line">function Func(x: double; px: byte; d: shortint): double; far;</div><div class="code_line">(*</div><div class="code_line">&nbsp;&nbsp;Функция для вычисления полинома в точке &#39;x&#39;</div><div class="code_line">&nbsp;&nbsp;x &nbsp;- в этой точке будет происходить расчет</div><div class="code_line">&nbsp;&nbsp;px - если 1, то результат будет = F(x)+x</div><div class="code_line">&nbsp;&nbsp;d &nbsp;- если 0, то F(x), 1 - F&#39;(x), -1 - F(x)/F&#39;(x)</div><div class="code_line">*)</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;bn, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { Это будет F(x) }</div><div class="code_line">&nbsp;&nbsp;cn: double; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { Это будет F&#39;(x) }</div><div class="code_line">&nbsp;&nbsp;j: byte; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Счетчик цикла ;) }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if px=1 then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Если px=1, то добавляем к рез-ту x }</div><div class="code_line">&nbsp;&nbsp; &nbsp;An[1]:=An[1]+1;</div><div class="code_line">{ Далее идет расчет по правилу Горнера &nbsp;}</div><div class="code_line">&nbsp;&nbsp;bn:=An[anMax];</div><div class="code_line">&nbsp;&nbsp;cn:=bn;</div><div class="code_line">&nbsp;&nbsp;for j:= anMax-1 downto 1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;bn:=An[j]+x*bn;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;cn:=bn+x*cn;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;bn:=An[0]+x*bn;</div><div class="code_line">{ В зависимости от d возвращаем результат }</div><div class="code_line">&nbsp;&nbsp;case d of</div><div class="code_line">&nbsp;&nbsp; &nbsp;-1: Func:=bn/cn;</div><div class="code_line">&nbsp;&nbsp; &nbsp; 0: Func:=bn;</div><div class="code_line">&nbsp;&nbsp; &nbsp; 1: Func:=cn;</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;Func:=bn;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">{ Забираем обратно свой x }</div><div class="code_line">&nbsp;&nbsp;if px=1 then</div><div class="code_line">&nbsp;&nbsp; &nbsp;An[1]:=An[1]-1;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Sign(x: double): shortint;</div><div class="code_line">{ Функция определения знака }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if x &#60; - Eps then</div><div class="code_line">&nbsp;&nbsp; &nbsp;Sign:=-1</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;if x &#62; Eps then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Sign:=1</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Sign:=0;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Get_X0(f: TFunc): double;</div><div class="code_line">(*</div><div class="code_line">&nbsp;&nbsp;Поиск начального приближения:</div><div class="code_line">&nbsp;&nbsp;Идет начальный просмотр функции и определение двух точек,</div><div class="code_line">&nbsp;&nbsp;между которыми функция меняят знак (проходит через 0).</div><div class="code_line">&nbsp;&nbsp;Где-то между этими точками лежит корень.</div><div class="code_line">*)</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;LookFrom = -10.0; &nbsp; &nbsp; { Поиск начинается с этой точки }</div><div class="code_line">&nbsp;&nbsp;step = 1; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { Шаг, с которым производится поиск }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;x0:=LookFrom;</div><div class="code_line">&nbsp;&nbsp;x1:=x0+eps;</div><div class="code_line">&nbsp;&nbsp;while Sign(f(x1,0,0)) = Sign(f(x0,0,0)) do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x0:=x1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x1:=x1+step;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Get_X0:= (x1+x0)/2;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Metod1(f: TFunc; x0: double): double;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;cnt: word;</div><div class="code_line">function TestFunc(x: double): boolean;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if abs(f(x,1,1)) &#62;= 1 then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;writeln(&#39; &nbsp;Ошибка: Невозможно расчитать результат!&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;writeln(&#39; &nbsp;Модуль производной в точке &#39;,x:0:6,&#39; больше 1&#39;,#10);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TestFunc:= false;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;TestFunc:= true;</div><div class="code_line">end;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Метод последовательных приближений:&#39;);</div><div class="code_line">&nbsp;&nbsp;if TestFunc(x0) then</div><div class="code_line">&nbsp;&nbsp; &nbsp;x1:=f(x0,1,0)</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;exit;</div><div class="code_line">{ &nbsp;x2:=f(x1,0)+x1;}</div><div class="code_line">&nbsp;&nbsp;cnt:=1;</div><div class="code_line">&nbsp;&nbsp;while abs(x1-x0) &#62; eps do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x0:=x1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if TestFunc(x0) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;x1:=f(x0,1,0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc(cnt)</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Metod1:=x1;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;x=&#39;, x1:0:6);</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Метод сошелся на &#39;,cnt,&#39; шаге.&#39;,#10);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Metod2(f: TFunc; x0: double): double;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;alph: double;</div><div class="code_line">&nbsp;&nbsp;cnt: word;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Усовершенствованный метод последовательных приближений:&#39;);</div><div class="code_line">&nbsp;&nbsp;x1:=f(x0,1,0);</div><div class="code_line">&nbsp;&nbsp;alph:=1/(1-f(x1,0,0)/(x1-x0));</div><div class="code_line">&nbsp;&nbsp;x2:=x1+alph*f(x1,0,0);</div><div class="code_line">&nbsp;&nbsp;cnt:=2;</div><div class="code_line">&nbsp;&nbsp;while abs(x2-x1) &#62; eps do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x0:=x1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x1:=x2;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;alph:=1/(1-f(x1,0,0)/(x1-x0));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x2:=x1+alph*f(x1,0,0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc(cnt)</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Metod2:=x2;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;x=&#39;, x2:0:6);</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Метод сошелся на &#39;,cnt,&#39; шаге.&#39;,#10);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Metod3(f: TFunc; x0: double): double;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;cnt: word;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Метод Бирге-Виетта:&#39;);</div><div class="code_line">&nbsp;&nbsp;x1:=x0-f(x0,0,-1);</div><div class="code_line">&nbsp;&nbsp;cnt:=1;</div><div class="code_line">&nbsp;&nbsp;while abs(x1-x0) &#62; Eps do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x0:=x1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x1:=x0-f(x0,0,-1);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc(cnt);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Metod3:=x1;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;x=&#39;, x1:0:6);</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Метод сошелся на &#39;,cnt,&#39; шаге.&#39;,#10);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;x0:=Get_X0(Func);</div><div class="code_line">&nbsp;&nbsp;Writeln;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;F(x)= -5.372 + 1.2493*x + 0.559*x^2 - 0.13*x^3&#39;);</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Eps = &#39;,eps:0:5,&#39; &nbsp;x0= &#39;,x0:0:6,#10);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Metod1(Func,x0);</div><div class="code_line">&nbsp;&nbsp;Metod2(Func,x0);</div><div class="code_line">&nbsp;&nbsp;Metod3(Func,x0);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Write(&#39;Press Enter to exit&#39;);</div><div class="code_line">&nbsp;&nbsp;Readln;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray"><span class='tag-size' data-value='7' style='font-size:7pt;'>Это сообщение было перенесено сюда или объединено из темы &quot;Решение уравнений&quot;</span></span>]]></description>
        <author>Romtek</author>
        <category>Pascal: Математика</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=100241&amp;view=findpost&amp;p=653753</guid>
        <pubDate>Tue, 22 Mar 2005 09:54:08 +0000</pubDate>
        <title>Численные методы</title>
        <link>https://forum.sources.ru/index.php?showtopic=100241&amp;view=findpost&amp;p=653753</link>
        <description><![CDATA[Romtek: <span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Решение уравнений</strong></span></span><br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{Автор: Ozzя}</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;a,b,x,e:real;</div><div class="code_line">&nbsp;</div><div class="code_line">{ Нелинейное уравнение (x-2)*lg(x+11)-1 }</div><div class="code_line">function f(x:real):real;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;f:=(x-2)*lg(x+11)-1;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ Функция, определяющая знак числа }</div><div class="code_line">function sgn(x:real):integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;sgn:=0;</div><div class="code_line">&nbsp;&nbsp;if x&#60;0.0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp;sgn:=-1;</div><div class="code_line">&nbsp;&nbsp;if x&#62;0.0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp;sgn:=1;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ Процедура, реализующая метод половинного деления }</div><div class="code_line">procedure dich (var a,b,x,e:real);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i:integer;</div><div class="code_line">&nbsp;&nbsp;r:real;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;i:=sgn(f(a));</div><div class="code_line">&nbsp;&nbsp;{ Повторяем до тех пор, пока интервал [a,b] не станет меньше &nbsp; }</div><div class="code_line">&nbsp;&nbsp;{ заданной погрешности е &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="code_line">&nbsp;&nbsp;while b-a&#62;e do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{ Определяем середину отрезка &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;x:=(a+b)/2;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{ Далее делаем выбор, какую из частей отрезка взять &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{ для дальнейшего уточнения корня &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{ Если левая часть уравнения f(x) есть непрерывная функция }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{ аргумента х, то корень будет находиться в той половине &nbsp; }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{ отрезка, на концах которой f(x) имеет разные знаки. &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;r:=f(x);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if sgn(r)=i then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;a:=x</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;b:=x</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;write(&#39;Введите значения интервала A,B? &#39;);</div><div class="code_line">&nbsp;&nbsp;readln(a,b);</div><div class="code_line">&nbsp;&nbsp;write(&#39;Введите требуемое значение точности E? &#39;);</div><div class="code_line">&nbsp;&nbsp;readln(e);</div><div class="code_line">&nbsp;&nbsp;dich(a,b,x,e);</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;X= &#39;,x);</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray"><span class='tag-size' data-value='7' style='font-size:7pt;'>Это сообщение было перенесено сюда или объединено из темы &quot;Решение уравнений&quot;</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray"><span class='tag-size' data-value='7' style='font-size:7pt;'>Это сообщение было перенесено сюда или объединено из темы &quot;<a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=89325' target='_blank'>Заготовка для &quot;Численных методов&quot;</a>&quot;</span></span>]]></description>
        <author>Romtek</author>
        <category>Pascal: Математика</category>
      </item>
	
      </channel>
      </rss>
	