(*~\Глагол\Отделы\ЧисАн\64\д\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                         ОТДЕЛ дМатрица;
(*============================================================================*
 * НАЗНАЧЕНИЕ: определение матриц действительных\вещ. чисел (64 разряда)
 *               и основные вычисления над ними
 *============================================================================*)

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

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

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

ВИД
                    Вид- = РЯД ИЗ дВектор.Вид;
  Доступ-= ДОСТУП К Вид;

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

(*----------------------------------------------------------------------------*
 * Код ошибки после выполнения функций
 *----------------------------------------------------------------------------*)
ПОСТ
  ВЫРОЖДЕНА-           =-1;  (* вырожденная матрица *)
  НЕТ_СХОДИМОСТИ-      =-2;  (* нет сходимости *)
  НЕ_ПоложитОПРЕДЕЛЕНа-=-3;  (* матрица не является положительно определенной *)
(*
ПОСТ
  МАЛОЕ = 1.D-20;               (* вместо 0. с точностью 64 разряда *)
*)


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


(*----------------------------------------------------------------------------*)
ЗАДАЧА^ умнСтрокиНаСтолбец-(дВектСтрока-,
                            дВектСтолбец-:дВектор.Вид):Вещ;
(*
 * Цель: умножение вектора-строки на вектор-столбец
 *)
(*----------------------------------------------------------------------------*)
ЗАДАЧА^ умнНаВектор-(дМатр-:дМатрица.Вид;             (* дМатр*дВход = дВыход *)
                     дВход-,
                     дВыход+:дВектор.Вид
                    );
(*
 * Цель: умножение действительной матрицы <дМатр> на вектор <дВход>
 *                 <дВыход>:=<дМатр>*<дВход>;
 *)
(*----------------------------------------------------------------------------*)
ЗАДАЧА^ Перемножить-(L-,A+:дМатрица.Вид);
(*
 * Цель: перемножение двух действ. матриц <L>*<L'>=<A>, где
 *                                            <L'> - транспонированная <L>   
 *)

(*----------------------------------------------------------------------------*
 * Переписывание действительных матриц, их строк и столбцов
 *----------------------------------------------------------------------------*)

ЗАДАЧА^ ОбменСтрок-   (A+:дМатрица.Вид; i,k:ЦЕЛ);
ЗАДАЧА^ ОбменСтолбцов-(A+:дМатрица.Вид; j,k:ЦЕЛ);

ЗАДАЧА^ Списать-(из-,в+:дМатрица.Вид);
(*
ЗАДАЧА^ СписатьСтолбецИзВектора-(из-: дВектор.Вид; в+:дМатрица.Вид; стлб:ЦЕЛ);
ЗАДАЧА^ СписатьВекторИзСтолбца- (из-:дМатрица.Вид; в+: дВектор.Вид; стлб:ЦЕЛ);
*)
ЗАДАЧА^ СписатьСтолбецИзВектора-(вект-: дВектор.Вид;
                                 матр+:дМатрица.Вид; стлб:ЦЕЛ
                                );           (* 0 <= стлб < РАЗМЕР(матр,1) *)
                          (*    вект[] -> матр[,стлб] *)
ЗАДАЧА^ СписатьВекторИзСтолбца-(матр-:дМатрица.Вид;
                                вект+: дВектор.Вид; стлб:ЦЕЛ
                               );           (* 0 <= стлб < РАЗМЕР(матр,1) *)
                          (* из[,стлб] -> вект[]      *)


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


(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА умнСтрокиНаСтолбец-(дВектСтрока-,
                           дВектСтолбец-:дВектор.Вид):Вещ;
(*
 * Цель: умножение вектора-строки на вектор-столбец
 *----------------------------------------------------------------------------*
 * До:    <дВектСтрока>  - входная действ. вектор-строка
 *        <дВектСтолбец> - входной действ. вектор-столбец
 * После: действительная сумма произведений элементов входных векторов
 *)
ПЕР
            суммаП,
                     Произведение:Вещ;  (* временные действительные *)
     j:ЦЕЛ;
            N:ЦЕЛ;                               (* размер вектора, N - любое *)
УКАЗ
(*-
  НаЭкран.ВсяЦепь("^ дМатрица.умнСтрокиНаСтолбец() ^");
-*)
            N:=РАЗМЕР(дВектСтолбец);
  ПРОВЕРИТЬ(N > 1);                           (* и остановить работу при N<=1 *)
(*
  дМатрВВ.наЭкран("^ дВектСтрока = %20.16e",дВектСтрока);
  дМатрВВ.наЭкран("^дВектСтолбец = %20.16e",дВектСтолбец);
*)
    суммаП:=0;            (* накопление в суммаП суммы произведений по j *)
  ОТ j:=0 ДО N-1 ВЫП
                     Произведение:=дВектСтрока[j]*дВектСтолбец[j];
    суммаП:=суммаП + Произведение;
(*-
          НаЭкран.Вещ4числа("^ Произведение= %20.16e, суммаП= %20.16e",
                               Произведение,
                                                      суммаП,          0,0
                           );
-*)
  КОН;
  ВОЗВРАТ суммаП
КОН умнСтрокиНаСтолбец;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА умнНаВектор-(дМатр-:дМатрица.Вид;              (* дМатр*дВход = дВыход *)
                    дВход-,
                    дВыход+:дВектор.Вид
                   );
(*
 * Цель: умножение действительной матрицы <дМатр> на вектор <дВход>
 *                <дВыход>:=<дМатр>*<дВход>;
 *----------------------------------------------------------------------------*
 * До:      <дМатр> - входная действительная матрица из NxN
 *          <дВход> - входной действительный  вектор из N,Y=X*M
 * После: <дВыход> - выходной действительный  вектор из N                     
 *)
ПЕР
     i(*,j*):ЦЕЛ;
(*-
            суммаП,
                     Произведение:Вещ;  (* временные действительные *)
-*)
            N:ЦЕЛ;                                 (* длина вектора N - любая *)
УКАЗ
(*-
  НаЭкран.ВсяЦепь("^ дМатрица.умнНаВектор() ^");
-*)
            N:=РАЗМЕР(дВход);
  ПРОВЕРИТЬ(N > 1);                           (* и остановить работу при N<=1 *)
(*
  дМатрВВ.наЭкран("^дВход = %20.16e",дВход);
*)
  ОТ i:=0 ДО N-1 ВЫП
(*-
      суммаП:=0;          (* накопление в суммаП суммы произведений по j *)
    ОТ j:=0 ДО N-1 ВЫП
                       Произведение:=дМатр[i,j]*дВход[j];
      суммаП:=суммаП + Произведение;
(*-
          НаЭкран.Вещ4числа("^ Произведение= %20.16e, суммаП= %20.16e",
                               Произведение,
                                                      суммаП,          0,0
                           );
-*)
    КОН;
    дВыход[i]:=суммаП
-*)
    дВыход[i]:=умнСтрокиНаСтолбец(дМатр[i],дВход);
  КОН;
(*
  дМатрВВ.наЭкран("^дВыход = %20.16e",дВыход^);
*)
КОН умнНаВектор;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Перемножить-(L-,A+:дМатрица.Вид);
(*
 * Цель: перемножение двух действ. матриц <L>*<L'>=<A>, где
 *                                            <L'> - транспонированная <L>    
 *)
ПЕР
  i,j,k,n:ЦЕЛ;
  summaProizv:Вещ;
УКАЗ
  n:=РАЗМЕР(L);
  ОТ i:=0 ДО n-1 ВЫП
    ОТ j:=0 ДО i ВЫП
      summaProizv:=0;
      ОТ k:=0 ДО j ВЫП
        summaProizv:=summaProizv + L[i,k]*L[j,k]
      КОН;
      A[i,j]:=summaProizv;
      ЕСЛИ i # j ТО
        A[j,i]:=summaProizv 
      КОН
    КОН 
  КОН
КОН Перемножить;


(*============================================================================*
 * Переписывание действительных матриц, их строк и столбцов
 *============================================================================*)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ОбменСтрок-(A+:дМатрица.Вид; i,k:ЦЕЛ);
ПЕР
  j:ЦЕЛ;
УКАЗ
  ОТ j:=0 ДО РАЗМЕР(A,1)-1 ВЫП
    дМатем.обмен(A[i,j],A[k,j]) 
  КОН
КОН ОбменСтрок;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ОбменСтолбцов-(A+:дМатрица.Вид; j,k:ЦЕЛ);
ПЕР
  i:ЦЕЛ;
УКАЗ
  ОТ i:=0 ДО РАЗМЕР(A,0)-1 ВЫП
    дМатем.обмен(A[i,j],A[i,k])
  КОН
КОН ОбменСтолбцов;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Списать-(из-,в+:дМатрица.Вид);
ПЕР
  i,j:ЦЕЛ;
УКАЗ
  ОТ i:=0 ДО   цМатем.мин(РАЗМЕР(из,0),РАЗМЕР(в,0))-1 ВЫП
    ОТ j:=0 ДО цМатем.мин(РАЗМЕР(из,1),РАЗМЕР(в,1))-1 ВЫП
      в[i,j]:=из[i,j] 
    КОН 
  КОН
КОН Списать;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СписатьСтолбецИзВектора-(вект-: дВектор.Вид;
                                матр+:дМатрица.Вид; стлб:ЦЕЛ
                               );           (* 0 <= стлб < РАЗМЕР(матр,1) *)
ПЕР                          (* вект[] -> матр[,стлб] *)
     i:ЦЕЛ;
УКАЗ
  ОТ i:=0 ДО цМатем.мин(РАЗМЕР(вект),РАЗМЕР(матр,0))-1 ВЫП
    матр[i,стлб]:=вект[i]                       (* i - номер строки в матрице *)
  КОН
КОН СписатьСтолбецИзВектора;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СписатьВекторИзСтолбца-(матр-:дМатрица.Вид;
                               вект+: дВектор.Вид; стлб:ЦЕЛ
                              );           (* 0 <= стлб < РАЗМЕР(матр,1) *)
ПЕР                         (* из[,стлб] -> вект[] *)
     i:ЦЕЛ;
УКАЗ
  ОТ i:=0 ДО цМатем.мин(РАЗМЕР(матр,0),РАЗМЕР(вект))-1 ВЫП
    вект[i]:=матр[i,стлб]                       (* i - номер строки в матрице *)
  КОН
КОН СписатьВекторИзСтолбца;

КОН дМатрица.
