(*~\Глагол\Отделы\ЛинАл\64\к\Ряд\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                             ОТДЕЛ крСистЛАУ;
(*============================================================================*
 * НАЗНАЧЕНИЕ: решение Систем Линейных алгебраических Уравнений
 *  (для комплексных в виде ряда из 2-х чисел с плавающей точкой в 64 разряда)
 *                              Матричный Анализ для комплексных (в виде ряда)
 *============================================================================*)

ИСПОЛЬЗУЕТ
 дМатем   ИЗ "..\..\..\..\..\Отделы\ЧисАн\64\д\",
 дВектор  ИЗ "..\..\..\..\..\Отделы\ЧисАн\64\д\",
 дМатрица ИЗ "..\..\..\..\..\Отделы\ЧисАн\64\д\",

 дСистЛАУ ИЗ "..\..\..\..\..\Отделы\ЛинАл\64\д\",

крМатем   ИЗ "..\..\..\..\..\Отделы\ЧисАн\64\к\Ряд\",
крВектор  ИЗ "..\..\..\..\..\Отделы\ЧисАн\64\к\Ряд\",
крМатрица ИЗ "..\..\..\..\..\Отделы\ЧисАн\64\к\Ряд\";
(*
крВектВВ  ИЗ "..\..\..\..\..\Отделы\ЧисАн\64\к\Ряд\ВводВывод",

  НаЭкран ИЗ "..\..\..\..\..\Отделы\Обмен\ВводВывод\";
*)

ВИД
(*
  Доступ- = ДОСТУП К Вид;
  Вид-    = РЯД ИЗ крВектор.Вид;
*)
        (* вид Вещ - это удвоенная точность 64 разряда (16 десятичных знаков) *)
  Вещ = дМатем.Вещ;                   (* локально *)


(*-оооооооооооооо- опережающие определения/заготовки задач -ооооооооооооооооо-*)


(*----------------------------------------------------------------------------*)
ЗАДАЧА^ РазложитьНаLU-(      A+:крМатрица.Вид;
                       строкиД+:дСистЛАУ.ДкРядуПерестановок):ЦЕЛ;
(*
 * Цель:  LU-разложение (A=L*U) квадратной матрицы A на два сомножителя L и U,
 *    где L - это нижняя треугольная матрица с единичной главной диагональю,
 *       а U - верхняя треугольная матрица. Эта задача используется
 *        совместно с задачей РешитьИзLU() для решения систем уравнений.
 *)
(*----------------------------------------------------------------------------*)
ЗАДАЧА^ РешитьИзLU-(A-:крМатрица.Вид;
                    b-: крВектор.Вид; строкиД:дСистЛАУ.ДкРядуПерестановок;
                    x+: крВектор.Вид);
(*
 * Цель:  решение системы уравнений после преобразования исходной матрицы A
 *        с помощью задачи РазложитьНаLU()
 *)


(*=рррррррррррррррррррррррр= реализация задач =рррррррррррррррррррррррррррррр=*)


(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА РазложитьНаLU-(     A+:крМатрица.Вид;
                      строкиД+:дСистЛАУ.ДкРядуПерестановок):ЦЕЛ;
(*
 * Цель:  LU-разложение (A=L*U) квадратной матрицы A на два сомножителя L и U,
 *    где L - это нижняя треугольная матрица с единичной главной диагональю,
 *       а U - верхняя треугольная матрица. Эта задача используется
 *        совместно с задачей РешитьИзLU() для решения систем уравнений.
 *----------------------------------------------------------------------------*
 * До:    <A>    - исходная комплексная матрица (в виде ряда)
 * После: <A>    - содержит элементы двух треугольных матриц - L и U
 *        <строкиД> - доступ к ряду из (действительных) номеров, т.е.
 *                   (вновь созданные записи о перестановках строк)
 * Ответ: 0 или ВЫРОЖДЕНА
 *)
ПЕР
  i,maxI,j,k,посл:ЦЕЛ;
  c,вед,t:Вещ;
  z,
  кСумма:крМатем.Вид;
  дВекД:дВектор.Доступ;
УКАЗ
  посл:=РАЗМЕР(A)-1;

  СОЗДАТЬ(  дВекД,посл+1);
  СОЗДАТЬ(строкиД,посл+1);

  ОТ i:=0 ДО посл ВЫП
    вед:=0;
    ОТ j:=0 ДО посл ВЫП
      c:=крМатем.мод(A[i,j]);
      ЕСЛИ c > вед ТО
        вед:=c 
      КОН 
    КОН;
    ЕСЛИ вед < дМатем.МашинEps ТО
      ВОЗВРАТ дМатрица.ВЫРОЖДЕНА
    КОН;
    дВекД[i]:=1/вед
  КОН;
  ОТ j:=0 ДО посл ВЫП
    ОТ i:=0 ДО j-1 ВЫП
      кСумма:=A[i,j];
      ОТ k:=0 ДО i-1 ВЫП
        крМатем.умножить(A[i,k],A[k,j],z);
(*      крМатем.вычесть(кСумма,z,кСумма)           *)
        крМатем.отнять(z,кСумма)      (* кСумма-=z *)
      КОН;
      A[i,j]:=кСумма
    КОН;
    maxI:=0;
    вед:=0;
    ОТ i:=j ДО посл ВЫП
      кСумма:=A[i,j];
      ОТ k:=0 ДО j-1 ВЫП
        крМатем.умножить(A[i,k],A[k,j],z);
(*      крМатем.вычесть(кСумма,z,кСумма)           *)
        крМатем.отнять(z,кСумма)      (* кСумма-=z *)
      КОН;
      A[i,j]:=кСумма;
      t:=дВекД[i]*крМатем.мод(кСумма);
      ЕСЛИ t > вед ТО
        вед:=t;
        maxI:=i
      КОН
    КОН;
    ЕСЛИ j # maxI ТО
      ОТ k:=0 ДО посл ВЫП
        крМатем.обмен(A[maxI,k],A[j,k]) 
      КОН;
      дВекД[maxI]:=дВекД[j]
    КОН;
    строкиД[j]:=maxI;
    ЕСЛИ крМатем.мод(A[j,j]) = 0 ТО
      крМатем.алгебрВид(дМатем.МАЛОЕ,дМатем.МАЛОЕ,A[j,j])
    КОН;
    ЕСЛИ j # посл ТО
      ОТ i:=j+1 ДО посл ВЫП
 (*     крМатем.делить(A[i,j],A[j,j],A[i,j])   *)
         крМатем.уменьшВкомпл(A[j,j],A[i,j])  
      КОН
    КОН
  КОН;
  ВОЗВРАТ 0
КОН РазложитьНаLU;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА РешитьИзLU-(A-:крМатрица.Вид;
                   b-: крВектор.Вид; строкиД:дСистЛАУ.ДкРядуПерестановок;
                   x+: крВектор.Вид);
(*
 * Цель:  решение системы уравнений после преобразования исходной матрицы A
 *        с помощью задачи РазложитьНаLU()
 *----------------------------------------------------------------------------*
 * До:    <A>   - исходная комплексная матрица A после задачи РазложитьНаLU()
 *        <b>   - комплексный вектор свободных членов
 *    <строкиД> - доступ к ряду из (действительных) номеров, т.е.
 *                   (записи о перестановках строк из РазложитьНаLU)
 * После: <x>   - комплексный вектор решения
 *)
ПЕР
  i,Ip,j,k,посл:ЦЕЛ;
  z,кСумма:крМатем.Вид;
УКАЗ
  посл:=РАЗМЕР(A)-1;
  k:=-1;
  ОТ i:=0 ДО посл ВЫП
    x[i]:=b[i]
  КОН;
  ОТ i:=0 ДО посл ВЫП
    Ip:=строкиД[i];
    кСумма:=x[Ip];
    x[Ip]:=x[i];
    ЕСЛИ k >= 0 ТО
      ОТ j:=k ДО i-1 ВЫП
        крМатем.умножить(A[i,j],x[j],z);
(*      крМатем.вычесть(кСумма,z,кСумма)           *)
        крМатем.отнять(z,кСумма)      (* кСумма-=z *)
      КОН 
    ИНАЧЕ 
      ЕСЛИ крМатем.мод(кСумма) # 0 ТО
        k:=i 
      КОН 
    КОН;
    x[i]:=кСумма
  КОН;
  ОТ i:=посл ДО 0 ПО -1 ВЫП
    кСумма:=x[i];
    ЕСЛИ i < посл ТО
      ОТ j:=i+1 ДО посл ВЫП
        крМатем.умножить(A[i,j],x[j],z);
(*      крМатем.вычесть(кСумма,z,кСумма)           *)
        крМатем.отнять(z,кСумма)      (* кСумма-=z *)
      КОН 
    КОН;
    крМатем.делить(кСумма,A[i,i],x[i])
  КОН
КОН РешитьИзLU;

КОН крСистЛАУ.