(*~\Глагол\Отделы\ЧисАн\32\к\Пара\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                        ОТДЕЛ кпВектор;
(*============================================================================*
 * НАЗНАЧЕНИЕ: определение векторов (рядов) из комплексных чисел,
 *      представленных в виде пары действительных <дВход,мВход> вида дВект.Вид
 *               и основные вычисления над этими комплексными парами-векторами
 *============================================================================*)

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

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

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

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

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


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


(*----------------------------------------------------------------------------*
 * арифметические действия над векторами из комплексных в виде пары действительных <дВход,мВход>
 *----------------------------------------------------------------------------*)

ЗАДАЧА^ умнНаВещ-(дВход- ,мВход- :дВектор.Вид; v:Вещ; 
                  дВыход+,мВыход+:дВектор.Вид);    (* кВыход:=кВход*v - умножение вектора на вещ. v *)
ЗАДАЧА^ делНаВещ-(дВход- ,мВход- :дВектор.Вид; v:Вещ; 
                  дВыход+,мВыход+:дВектор.Вид);    (* кВыход:=кВход/v - деление   вектора на вещ. v *)

ЗАДАЧА^ увеличВдейств-(                        v:Вещ;
                  дВект+,мВект+:дВектор.Вид);      (* кВект *= v - увеличить себя в действ. число v раз *)
ЗАДАЧА^ уменьшВдейств-(                        v:Вещ;
                  дВект+,мВект+:дВектор.Вид);      (* кВект /= v - уменьшить себя в действ. число v раз *)

ЗАДАЧА^ умнНаКомпл-(дВход- ,мВход- :дВектор.Вид; дW,мW:Вещ;
                    дВыход+,мВыход+:дВектор.Вид); (* кВыход:=кВход*w - умножение вектора на компл. w *)
ЗАДАЧА^ делНаКомпл-(дВход- ,мВход- :дВектор.Вид; дW,мW:Вещ;
                    дВыход+,мВыход+:дВектор.Вид); (* кВыход:=кВход/w - деление   вектора на компл. w *)

ЗАДАЧА^ увеличВкомпл- (                          дW,мW:Вещ;
                  дВект+,мВект+:дВектор.Вид);        (* кВект *= w - увеличить себя в компл. число w раз *)
ЗАДАЧА^ уменьшВкомпл- (                          дW,мW:Вещ;
                  дВект+,мВект+:дВектор.Вид);        (* кВект /= w - уменьшить себя в компл. число w раз *)

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

ЗАДАЧА^ Списать-(дВход-,  мВход-,
                 дВыход+,мВыход+:дВектор.Вид);
(* Цель: Переписывание комплексных векторов *)


(*----------------------------------------------------------------------------*)
ЗАДАЧА^ ДПФi-(прямое-:КЛЮЧ;       гармоника_i:ЦЕЛ;
              дВход-, мВход- :дВектор.Вид;
              дВых_i+,мВых_i+:Вещ);
(* Цель:  прямое/обратное Дискретное Преобразование Фурье для i-й гармоники
 *           (НЕ алгоритм Герцеля, а от Издателя Глагола)
 *                                           [в спектре(ДПФ)/в сигнале(ОДПФ)] *) 


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


(*============================================================================*
 * арифметические действия над векторами из комплексных в виде пары действительных <дВход,мВход>
 *============================================================================*)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА умнНаВещ-(дВход- ,мВход- :дВектор.Вид; v:Вещ; 
                 дВыход+,мВыход+:дВектор.Вид);    (* кВыход:=кВход*v - умножение вектора на вещ. v *)
(* Цель: умножение комплексного вектора, представленного в виде пары
 * действительных векторов <дВход,мВход> на вещественное v -> <дВыход,мВыход> *)
ПЕР
  N,                                               (* длина вектора N - любая *)
  i:ЦЕЛ;
УКАЗ
  N:=РАЗМЕР(дВход);
                  (* нормировка на вещественное v
                комплексного вектора в виде пары действительных <дВход,мВход> *)
  ОТ i:=0 ДО N-1 ВЫП
    кпМатем.умножить(дВход[i], мВход[i], v,
                     дВыход[i],мВыход[i])          (* кВыход[i] = кВход[i]*v  *)
  КОН
КОН умнНаВещ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА делНаВещ-(дВход- ,мВход- :дВектор.Вид; v:Вещ; 
                 дВыход+,мВыход+:дВектор.Вид);    (* кВыход:=кВход/v - деление   вектора на вещ. v *)

(* Цель: деление комплексного вектора, представленного в виде пары
 * действительных векторов <дВход,мВход> на вещественное v -> <дВыход,мВыход> *)
ПЕР
  N,                                               (* длина вектора N - любая *)
  i:ЦЕЛ;
УКАЗ
  N:=РАЗМЕР(дВход);
                  (* нормировка на вещественное 1/v
                комплексного вектора в виде пары действительных <дВход,мВход> *)
  ОТ i:=0 ДО N-1 ВЫП
    кпМатем.делить(дВход[i], мВход[i], v,
                   дВыход[i],мВыход[i])            (* кВыход[i] = кВход[i]/v  *)
  КОН
КОН делНаВещ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА увеличВдейств-(                        v:Вещ;
                 дВект+,мВект+:дВектор.Вид);      (* кВект *= v - увеличить себя в действ. число v раз *)
(* Цель: умножение комплексного вектора, представленного в виде пары
 * действительных векторов <дВект,мВект> на вещественное v -> <дВект,мВект> *)
ПЕР
  N,                                               (* длина вектора N - любая *)
  i:ЦЕЛ;
УКАЗ
  N:=РАЗМЕР(дВект);
                  (* нормировка на вещественное v
                комплексного вектора в виде пары действительных <дВект,мВект> *)
  ОТ i:=0 ДО N-1 ВЫП
    кпМатем.увеличВдейств(            v,
                   дВект[i],мВект[i])                       (* кВект[i] *= v  *)
  КОН
КОН увеличВдейств;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА уменьшВдейств-(                        v:Вещ;
                 дВект+,мВект+:дВектор.Вид);      (* кВект /= v - уменьшить себя в действ. число v раз *)
(* Цель: деление комплексного вектора, представленного в виде пары
 * действительных векторов <дВект,мВект> на вещественное v -> <дВект,мВект> *)
ПЕР
  N,                                               (* длина вектора N - любая *)
  i:ЦЕЛ;
УКАЗ
  N:=РАЗМЕР(дВект);
                  (* нормировка на вещественное 1/v
                комплексного вектора в виде пары действительных <дВект,мВект> *)
  ОТ i:=0 ДО N-1 ВЫП
    кпМатем.уменьшВдейств(            v,
                   дВект[i],мВект[i])                       (* кВект[i] /= v  *)
  КОН
КОН уменьшВдейств;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА умнНаКомпл-(дВход- ,мВход- :дВектор.Вид; дW,мW:Вещ;
                   дВыход+,мВыход+:дВектор.Вид); (* кВыход:=кВход*w - умножение вектора на компл. w *)
(*      умножение комплексного вектора <дВход,мВход> на комплексное <дW,мW>:
            <дВыход,мВыход> = <дВход,мВход>*<дW,мW>                           *)
ПЕР
  N,
  i:ЦЕЛ;
УКАЗ
  N:=РАЗМЕР(кВход);
              (* нормировка на комплексное w (обычное комплексное умножение)
                комплексного вектора в виде пары действительных <дВход,мВход> *)
  ОТ i:=0 ДО N-1 ВЫП
    кпМатем.умножить(дВход[i], мВход[i], дW,мW,
                     дВыход[i],мВыход[i])         (* кВыход[i] = кВход[i]*w   *)
  КОН
КОН умнНаКомпл;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА делНаКомпл-(дВход- ,мВход- :дВектор.Вид; дW,мW:Вещ;
                   дВыход+,мВыход+:дВектор.Вид); (* кВыход:=кВход/w - деление   вектора на компл. w *)
(*      умножение комплексного вектора <дВход,мВход> на комплексное <дW,мW>:
            <дВыход,мВыход> = <дВход,мВход>*<дW,мW>                           *)
ПЕР
  N,
  i:ЦЕЛ;
УКАЗ
  N:=РАЗМЕР(кВход);
              (* нормировка на комплексное 1/w (обычное комплексное деление)
                комплексного вектора в виде пары действительных <дВход,мВход> *)
  ОТ i:=0 ДО N-1 ВЫП
    кпМатем.делить(дВход[i], мВход[i],   дW,мW,
                   дВыход[i],мВыход[i])           (* кВыход[i] = кВход[i]*w   *)
  КОН
КОН делНаКомпл;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА увеличВкомпл- (                          дW,мW:Вещ;
                 дВект+,мВект+:дВектор.Вид);        (* кВект *= w - увеличить себя в компл. число w раз *)
(* Цель: умножение комплексного вектора, представленного в виде пары
 * действительных векторов <дВект,мВект> на комплексную пару дW,мW -> <дВект,мВект> *)
ПЕР
  N,                                               (* длина вектора N - любая *)
  i:ЦЕЛ;
УКАЗ
  N:=РАЗМЕР(дВект);
                  (* нормировка на комплексное w
                комплексного вектора в виде пары действительных <дВект,мВект> *)
  ОТ i:=0 ДО N-1 ВЫП
    кпМатем.увеличВкомпл(           дW, мW,
                   дВект[i],мВект[i])                       (* кВект[i] *= w  *)
  КОН
КОН увеличВкомпл;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА уменьшВкомпл- (                          дW,мW:Вещ;
                 дВект+,мВект+:дВектор.Вид);        (* кВект /= w - уменьшить себя в компл. число w раз *)
(* Цель: деление комплексного вектора, представленного в виде пары
 * действительных векторов <дВект,мВект> на комплексную пару дW,мW -> <дВект,мВект> *)
ПЕР
  N,                                               (* длина вектора N - любая *)
  i:ЦЕЛ;
УКАЗ
  N:=РАЗМЕР(дВект);
                  (* нормировка на комплексное 1/w
                комплексного вектора в виде пары действительных <дВект,мВект> *)
  ОТ i:=0 ДО N-1 ВЫП
    кпМатем.уменьшВкомпл(            дW, мW,
                   дВект[i],мВект[i])                       (* кВект[i] /= w  *)
  КОН
КОН уменьшВкомпл;


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

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


(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ДПФi-(прямое-:КЛЮЧ;       гармоника_i:ЦЕЛ;
             дВход-, мВход- :дВектор.Вид;
             дВых_i+,мВых_i+:Вещ);
(* Цель:  прямое/обратное Дискретное Преобразование Фурье для i-й гармоники
 *           (НЕ алгоритм Герцеля, а от Издателя Глагола)
 *----------------------------------------------------------------------------*
 * До:    <прямое> - логическая/КЛЮЧ переменная - признак
 *                           прямого <ВКЛ>                      ( ДПФ)
 *                     или обратного <ОТКЛ> ДПФ-преобразования  (ОДПФ)
 *        <гармоника_i> - номер заданной комплексной гармоники в вых.спектре
 *        <дВход,мВход> - входной комплексный вектор в виде пары
 *          действительных векторов - временной сигнал(ДПФ)/спектр(ОДПФ)
 * После: <дВых_i,мВых_i> - i-й комплексный коэффициент разложения входа
 *                         в виде пары вещественных <действительное;мнимое>
 *                                           [в спектре(ДПФ)/в сигнале(ОДПФ)] *) 
ПЕР
  N,                                               (* длина вектора N - любая *)
  j:ЦЕЛ;
  v,
  дваПИнаN:Вещ;
  дX,мX,дY,мY,
  дК,мК,
  дYi,мYi:Вещ;
УКАЗ
  N:=РАЗМЕР(дВход);
  ПРОВЕРИТЬ(N > 1);                           (* и остановить работу при N<=1 *)
(*
  кпВектВВ.Вывод("^дВход,мВход = (%24.17e;%24.17e)",дВход,мВход);
*)
  (* постоянный множитель в аргументе комплексных ДПФ-экспонент дX,мX и дY,мY *)
  ЕСЛИ прямое ТО (* прямое=ВКЛ *)
                                      дваПИнаN:=-Матем.ДваПИ/N       (* в ДПФ *)
  ИНАЧЕ          (* прямое=ОТКЛ, т.е. обратное *)
                                      дваПИнаN:=+Матем.ДваПИ/N      (* в ОДПФ *)
  КОН;
                         (* вычисление ДПФ-экспонент: дX,мX и дY,мY *)
      кпМатем.expДПФ(-2*гармоника_i*дваПИнаN,дX,мX);  (* кX =<cos(-2*i*дваПИнаN);
                                                              sin(-2*i*дваПИнаN)> *)
                                                      (* кX:=кY*кY; - ? *)
      кпМатем.expДПФ(  -гармоника_i*дваПИнаN,дY,мY);  (* кY =<cos(  -i*дваПИнаN);
                                                              sin(  -i*дваПИнаN)> *)
                     (* dW=кY *)
  v:=2*дY;                                    (* v - постоянный вещ.множитель *)

                              (* накопление в Yi=<0;0> суммы комплексных по j *)
  дYi:=кпМатем.дКомплексногоНОЛЯ;
  мYi:=кпМатем.мКомплексногоНОЛЯ;

  ОТ j:=0 ДО N-1 ВЫП
    кпМатем.умнВ(дY,мY,v,дК,мК);      (*               К      = кY * v        *)
    кпМатем.выч(дК,мК,дX,мX,дК,мК);   (*             К=К - кX = кY * v - кX   *)

    дX:=дY;   мX:=мY;                 (* кX:=кY, кY:=К - для следующего j     *)
        дY:=дК;   мY:=мК;

    кпМатем.суммаПроизведений(дВход[j],мВход[j],дК,мК,дYi,мYi);
                             (* Yi:=Yi + кВход[j]*К - накопление произведений *)
(*
    кнКомпл.умн(кВход[j],к,к);         (*        К = кВход[j]*К               *)
    кнКомпл.доб(Yi,к,Yi)               (* Yi:=Yi+К  - накопление произведений *)
*)
  КОН;
  дВых_i:=дYi;
  мВых_i:=мYi
КОН ДПФi;

КОН кпВектор.
