(*~\Глагол\ПриложенияЛинАл\32\д\СистЛАУдейств\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                                    ОТДЕЛ ПроSV+;
(*============================================================================*
 * НАЗНАЧЕНИЕ: решение систем линейных уравнений (A*x=b) методом SV разложения
 * ПРИМЕЧАНИЯ: 
 *     Система уравнений записана в файле "ПроМатр2.дан".
 *     В этом файле 1-я строка содержит размер матрицы A
 *  (число строк и столбцов), в следующих строках записанны значения элементов
 *  матрицы A, потом на отдельной строке размер матрицы свободных членов B
 *  (число векторов b и их размер), а далее значения элементов матрицы B, 
 *  в которой строки являются векторами b.
 *     Прямоугольная матрица A (N на M, с N >= M) раскладывается на три
 *  сомножителя (A=U*S*V'), где U (N на M) состоит из столбцов - собственных
 *  векторов, S (M на M) - диагональная матрица с элементами >= 0 (собственные
 *  значения) и V (M на M) ортогональная матрица. Близкие к 0 (отклонение
 *  задается пользователем) собственные значения обнуляются. Решение 
 *  ищется в виде x = V*Diag(1/S(i))*U'*b, для S(i) # 0.
 *     Редактируя таким способом собственные значения S, можно успешно
 *  применять этод метод для решения систем уравнений с вырожденными
 *  и псевдо-вырожденными матрицами.
 *     Если матрица A вырождена, то возможно два случая:
 *  1) Если система недоопределена, то метод возвращает вектор x
 *     с минимальной нормой. 
 *  2) Если система несовместна, то метод возвращает такой вектор x,
 *     для которого A*x является наилучшим приближением к b (по норме). 
 *============================================================================*)

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

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

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

  ИзФайла ИЗ "..\..\..\..\Отделы\Обмен\ВводВывод\",
  НаЭкран ИЗ "..\..\..\..\Отделы\Обмен\ВводВывод\";

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Голова;
ПОСТ                      (* допуск для обнуления соб.векторов 64-х разрядная *)
  ДОПУСК=1.D-8;  (* собственные значения обнуляются, если они более
                  * чем в ДОПУСК раз меньше наибольшего собственного значения *)
ПЕР
  n :ЦЕЛ;  (* размер вектора свободных членов *)
  nv:ЦЕЛ;  (* число векторов свободных членов *)

  A:дМатрица.Доступ; (* матрица системы *)
  s: дВектор.Доступ; (* собственные значения *)
  v:дМатрица.Доступ; (* ортогональная матрица *)
  B:дМатрица.Доступ; (* вектора свободных членов *)
  X:дМатрица.Доступ; (* вектора решения *)

  i:ЦЕЛ; 
  ч:ИзФайла.ДкПотоку;

УКАЗ
  ч:=дМатрВВ.ОткрытиеФайла("ПроМатр2.дан");
  A:=дМатрВВ.изФайла(ч);
  B:=дМатрВВ.изФайла(ч);
             ИзФайла.Закрыть(ч);
  nv:=РАЗМЕР(B^,0);
  n :=РАЗМЕР(B^,1);

  СОЗДАТЬ(s,n);
  СОЗДАТЬ(v,n,n);
  СОЗДАТЬ(X,nv,n);

  НаЭкран.ВсяЦепь("^Исходная матрица:^");

  дМатрВВ.наЭкран("%10.5f",A^);

  НаЭкран.ВсяЦепь("^Вектора свободных членов:^");
  ОТ i:=0 ДО nv-1 ВЫП
    дВектВВ.наЭкран("%10.5f",B[i])
  КОН;
   (* После выполнения РазложитьНаSV матрица U оказывается на месте матрицы A *)
  ЕСЛИ
       дСистЛАУ.РазложитьНаSV(A^,s^,v^) = 0
  ТО
                                (* обнуляем незначимые сингулярные значения   *)
    дСистЛАУ.ОбнулитьS(s^,УЗК(ДОПУСК));

                     (* решаем систему для каждого вектора свободных членов b *)
    НаЭкран.ВсяЦепь("^Вектора решения:^");

    ОТ i:=0 ДО nv-1 ВЫП
      дСистЛАУ.РешитьИзSV(A^,s^,v^,B[i],X[i]); 
      дВектВВ.наЭкран("%10.5f",X[i])
    КОН
  ИНАЧЕ
    НаЭкран.ВсяЦепь("^Нет схождения!^")
  КОН
КОН Голова;

(*-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-*)
УКАЗ
  Голова
КОН ПроSV.
