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

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

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

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

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

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

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


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


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

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

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

ЗАДАЧА^ Списать-(из-,в+:дМатрица.Вид);
ЗАДАЧА^ СписатьСтолбецИзВектора-(из-: дВектор.Вид; в+:дМатрица.Вид; стлб:ЦЕЛ);
ЗАДАЧА^ СписатьВекторИзСтолбца- (из-:дМатрица.Вид; в+: дВектор.Вид; стлб:ЦЕЛ);


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


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

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

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

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

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

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

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

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