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

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

крМатем   ИЗ "..\..\..\..\..\Отделы\ЧисАн\32\к\Ряд\";  
(*
кнЦОС     ИЗ "..\..\..\..\..\Отделы\ЦОС\32\к\Набор\";

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

ВИД
  Доступ- = ДОСТУП К Вид;            (* доступ к вектору из комплексных чисел вида ряд [0,1] *)
  Вид-    = РЯД ИЗ крМатем.Вид;               (* вектор  из комплексных чисел вида ряд [0,1] *)

        (* вид Вещ - это удвоенная точность 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 раз *)


(*----------------------------------------------------------------------------*
 * Переписывание векторов из комплексных в виде ряда
 *----------------------------------------------------------------------------*)

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


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


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


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

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

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

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

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

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

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

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

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


(*============================================================================*
 * Переписывание векторов из комплексных в виде ряда
 *============================================================================*)

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


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

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

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

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

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

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