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

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

 дВектор  ИЗ "..\..\..\..\..\Отделы\ЧисАн\64\д\",
 дМатрица ИЗ "..\..\..\..\..\Отделы\ЧисАн\64\д\",

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

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

кпВектВВ  ИЗ "..\..\..\..\..\Отделы\ЧисАн\64\к\Пара\ВводВывод",

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

ВИД
        (* вид Вещ - это удвоенная точность 64 разряда (16 десятичных знаков) *)
  Вещ = дМатем.Вещ;                   (* локально *)


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


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


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


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

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

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

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

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

  k:=-1;
  ОТ i:=0 ДО последний ВЫП
    Рд[i]:=Bд[i];
    Рм[i]:=Bм[i]
  КОН;
  ОТ i:=0 ДО последний ВЫП
    Ip:=строкиД[i];

    Sд:=Рд[Ip];
    Sм:=Рм[Ip];

    Рд[Ip]:=Рд[i];
    Рм[Ip]:=Рм[i];

    ЕСЛИ k >= 0 ТО
      ОТ j:=k ДО i-1 ВЫП
        кпМатем.умножить(Aд[i,j],Aм[i,j],Рд[j],Рм[j],Zд,Zм);
(*      кпМатем.вычесть(Sд,Sм,Zд,Zм,Sд,Sм) *) (* S  = S-Z *)
        кпМатем.отнять(Zд,Zм,Sд,Sм)           (* S -= Z   *)
      КОН 
    ИНАЧЕ 
      ЕСЛИ кпМатем.мод(Sд,Sм) # 0 ТО
        k:=i 
      КОН 
    КОН;
    Рд[i]:=Sд;
    Рм[i]:=Sм
  КОН;
  ОТ i:=последний ДО 0 ПО -1 ВЫП
    Sд:=Рд[i];
    Sм:=Рм[i];

    ЕСЛИ i < последний ТО
      ОТ j:=i+1 ДО последний ВЫП
        кпМатем.умножить(Aд[i,j],Aм[i,j],Рд[j],Рм[j],Zд,Zм);
(*      кпМатем.вычесть(Sд,Sм,Zд,Zм,Sд,Sм) *) (* S  = S-Z *)
        кпМатем.отнять(Zд,Zм,Sд,Sм)           (* S -= Z   *)
      КОН 
    КОН;
    кпМатем.делить(Sд,Sм,Aд[i,i],Aм[i,i],Рд[i],Рм[i])
  КОН
КОН РешитьИзLU;

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

