Работа в Линуксе и Фурье-преобразования

Публикация рассчитана на людей, которые хотят освоить работу в Линуксе.

Почти всем радиотехникам известно, что сигнал любой формы может быть разложен на составляющие его гармонические косинусоидальные колебания с помощью преобразования Фурье. Разложить-то мы его разложим. Это делают все анализаторы спектров и даже современные цифровые осциллографы. Но как проверить, что полученный спектр соответствует сигналу? Как убедиться, что пазлы соберутся обратно? Как убедится, что после сборки получится мясорубка а не пулемет, как в том анекдоте?

Деление проверяется умножением. Сложение проверяется вычитанием. Извлечение корня — возведением в степень. Преобразование Фурье проверяется обратным преобразованием Фурье. (Удивил!)

Иначе говоря, если мы заставим работать много-много косинусоидальных генераторов с заданными частотами и заданной начальной фазой, и просуммируем (сложим) все их сигналы, то должны получить исходную форму сигнала. Теоретически это так.

Практически же никогда не бывает много-много свободных генераторов, поэтому приходится довольствоваться всего нескольким штуками. Это если речь идет о физических генераторах. Если речь идет о математических генераторах (программная реализация), то их количество может быть значительно больше. Главное чтобы хватало быстродействия компа или микроконтроллера.

Однако, с одной стороны это любопытно — поиграться с теорией. А с другой — вроде как и нафиг не надо, других более полезных дел всегда полно. У меня периодически чесались руки (проверить теорию), но как-то все не хватало времени заняться. Поэтому, идея так и оставалась нереализованной. Времени много убьешь, а результат — никому не нужен, только мне одному. Вот так я и дрейфовал по жизни много лет с голубой мечтой идиота.

Дрейфовал, пока мне в руки попал учебник физики младшей дочери (Мякишев. «Физика. Колебания и волны. Учебник для углубленного изучения.) Там на 43-й странице нарисована морда лица какой-то тетеньки, а так же профиль ее морды с намеком что это радиотехнический сигнал. О-о, как!

Ка можно видеть, рисунок выполнен с несколькими ошибками, которые я по возможности подправил карандашом:

— ось абсцисс была подписана неправильно: w (Омега) вместо wt.
— профиль морды повернуть на 90 градусов, то есть для профиля перепутаны оси координат.
— зачем-то отчеркнута вертикальная линия. Если предположить, что это ось абсцисс (проведена вертикально, что само по себе граничит с непониманием автора природы вещей, которые он излагает), то почему тогда отсутствует ось ординат y(t)?

Короче, не графики, а реклама Орифлейма. Для блондинок. Страсти много, а ценной информации — ноль.

Под графиком приведена страшная формула. Вот за нее-то я и зацепился.

И хотя сама формула также написана с такими же идиотским ошибками, но в ней присутствуют все составляющие, необходимые для проверки теории восстановления сигнала.

Отмечу ошибки в формуле. Вдруг кто-нибудь из учителей или редакторов читает мой блог. Вдруг захочется исправить ошибки или вдохновить школоту на подвиги. Тема-то интересная!

Во первых, я бы написал не просто y (игрек), а — y(t) (игрек от тэ). Школьники уже знают, что это означает. (Зависимость функции y от аргумента t). Таким образом, мы даем понимание, что функция y — функция во времени, то есть сигнал.

Во вторых, во всех слагаемых под синусом указано только w (омега), а не wt. А это у же более тяжкое преступление.

Таким образом, формулу следует написать так:

y(t) = 49.6 sin(wt + 302) + 17.4 sin(2wt + 298) + 13.8 sin(3wt + 195) + …

А вот тут начинается самое интересное для Линуксойдов. Если вы работает только в Виндусе, то далее вам будет читать неинтересно. Не тратьте свое время, займитесь другими делами. А Линуксойдов приглашаю к дальнейшему ознакомлению.

Я хотел бы рассказать вам как я работаю в Линуксе, как пишу программы и как вообще организую свое место программиста. Только это будет все сделано на конкретном примере и без каких-либо намеков на универсальность. Да, и сразу хочу предупредить, что я не претендую на истину. У каждого свой стиль работы. Я просто рассказываю, как я это делаю.

Итак, для проверки теории обратного преобразования Фурье я решил написать на языке Си программку. Я планирую, что программа будет выводить результаты расчетов на консоль. Перехватив вывод я их сохраню в файле. Потом этот файл скормлю программе, которая мастерски строит графики. В результате у меня будет получен на экране график, напоминающий морду лица тетеньки из учебника. Причем, я обращаю ваше внимание на то, что я прикладываю со своей стороны минимальные усилия для достижения результата.

Я начинаю новую работу. Начинаю новый проект. Для этого я создаю новый директорий, в котором я собираюсь «хулиганить». Я думаю, что имя waves для директория будет самое подходящее.

Я нахожусь в графической консоли, то есть та среда (окружение), которое получается после загрузки операционки. То есть на экране отображается рабочий стол  с «нескучными обоями».

Я нажимаю заветную комбинацию Ctrl-Alt-T для открытия окна псевдоконсоли.

Затем в этом окне выполняю команду создания директория и вхожу в него:

$ mkdir waves
$ cd waves

Далее мне нужно открыть окно текстового редактора, а в нем Си-шный файл. Я это делаю следующей командой:

$ gedit waves &

Обратите внимание на знак & (амперсенд) в конце команды. Его наличие скажет обработчику консольных команд запустить редактор и снова начать принимать команды. Таким образом редактор будет выполняться как независимое от псевдоконсоли приложение, а консоль не будет зависеть от редактора. Иначе, то есть без этого значка, консоль приступит к выполнению команд только после закрытия окна редактора. И хотя она будет продолжать принимать ввод команд с клавиатуры, но исполнять их не будет.

Итак, у меня на экране следующая картинка:

С помощью комбинации Alt-Tab я перехожу в окно редактора. В редакторе набираю следующий текст программы:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Сначала определим тип
typedef struct harm {
  double Amp;  // Амплитуда
  double Phy;  // Фаза
} harm_t;

// Теперь создадим массив гармоник и сразу проинициализируем его
harm_t harm_ar[18] =
{
  {49.6, 302},
  {17.4, 298},
  {13.8, 195},
  {7.1, 215},
  {4.5, 80},
  {0.6, 171},
  {2.7, 34},
  {0.6, 242},
  {1.6, 331},
  {1.3, 208},
  {0.3, 89},
  {0.5, 229},
  {0.7, 103},
  {0.3, 305},
  {0.4, 169},
  {0.5, 230},
  {0.5, 207},
  {0.4, 64}
};

const double Pi = 3.14159;
const double dt = 0.0001;  // величина квант времени для вычислений

// Согласно времени t функция вычисляет и возвращает амплитуду сигнала
double face(double t)
{
  double y;    // Амплитуда сигнала
  double phy;  // Угол в радианах
  int i;

  y = 0.0;
  for (i = 0; i < (sizeof (harm_ar) / sizeof (harm_t)); i++)
  {
    phy = Pi * harm_ar[i].Phy / 180.0;  // Переводим градусы в радианы
    y += harm_ar[i].Amp * sin(2.0 * Pi * t * (i + 1.0) + phy);  // Вычисляем амплитуду
  }

  return y;
}

int main(void)
{
  double t;       // Время
  double face_y;  // Амплитуда

  for (t = 0; t < 1.0; t += dt)
  {
    face_y = face(t);  // Находим амплитуду для заданного времени
    printf("%f %f\n", t, face_y);  // Результат выводим в стандартный поток
  }

  return EXIT_SUCCESS;
}

Вам проще — вам нет необходимости набирать весь этот текст. Наверняка вы уже умеете копипастить.

Текст программы набран, нужно срочно его сохранить. Находясь в окне редактора нажимаю на Ctrl-S. Текст сохранен.

Теперь возвращаюсь обратно в окно псевдоконсоли, для этого нажимаю на Alt-Tab.

Следующее действие — компиляции программы. Программа достаточно примитивная и поэтому создавать для нее Make-файл не имеет смысла, компилировать буду прямо из командной строки:

$ gcc -o waves -lm waves.c

Вроде как ничего не произошло? На самом деле все прошло удачно. Одно из правил Unix-way состоит в том, чтобы не шуметь (не создавать ненужный информационный шум), если все идет в штатном режиме. Чтобы убедится, что исполняемый файл создан, выполните команду ls:

$ ls -l

Теперь нужно запустить программу, а ее вывод направить в текстовый файл. Я это сделаю следующим образом:

$ ./waves > face

Точка и слеш в начале строки жизненно необходимы. Это только в Виндовсе и в DOS-е по умолчанию запускаются проги, которые находятся в текущей папке. В целях безопасности в Линуксе это не практикуется, и более того, это считается даже вульгарным — позволять запускать прогу в текущем директории. И это тоже Unix-way.

На следующем скриншоте я попытался запустить прогу по-Вендовому, на что получил законный «отлуп» от системы. Правильный запуск проги опять закончился ничем. Но нас не обманешь! Команда ls позволяет удостовериться в истинности — в директории появился еще один файл:

Теперь наши с вами пути возможно не на долго разойдутся. Компилятор gcc обычно в Линуксе устанавливается сразу, поэтому можно сразу писать программы и компилировать. А вот что касается профессионального инструмента научных работников для построения всяких-там графиков, то его нужно устанавливать.

Если у вас все еще не установлен gnuplot, то давайте прервемся на 15 минут и установим его.

Для начала выполним подновление списков программ, а потом произведем инсталляцию:

$ sudo apt-get update
$ sudo apt-get install gnuplot

Надеюсь, что у вас все идет нормально. Если нет, задавайте мне вопросы. Постараюсь помочь.

Так или иначе gnuplot установлен. И сейчас нужно его запустить. Но для этого дела я использую дополнительную вкладку консольного окна, которую открываю через … э-э …

В общем, если у вас переключатель раскладки клавиатура не на Ctrl-Shift, то вы можете нажать Ctrl-Shift-T, и у вас в окне консоли образуется еще одна вкладка, еще одно окно псевдоконсоли. Мне же приходится по-Вендовому тыкать мышкой.

Переходим на новую вкладку. К стати, переход между вкладками — будь это вкладки окна псевдоконсоли или окна текстового редактора gedit — осуществляется комбинациями Alt-1, Alt-2, Alt-3 и т.д. Цифра соответствует номеру вкладки.

К стати, заметьте, что новая вкладка открылась в том же самом директории. Удобно. Спасибо разработчикам!

Находясь во второй вкладке набираем команду для запуска gnuplot:

$ gnuplot

Здесь можно обойтись без амперсенда.

Теперь мы находимся в среде gnuplot, о чем свидетельствет подсказка в начале командной строки. Таким образом, все команды, которые мы зададим, будет интерпретировать и исполнять gnuplot.

Нам много не надо — нам нужно только построить график. Задаем команду:

gnuplot> plot "./face" w l

На экране должно появиться еще одно окно, в котором будет нарисован профиль морды лица, повернутой вверх:

Описание процесса заняло больше времени, чем сам процесс.

Я преднамеренно не расписываю как работать с gnuplot. Это очень большая и интересная тема. И, честно говоря, меня распирает желание рассказать вам как и с чего начать. Надеюсь, что скоро начну делиться опытом.

А пока мне остается рассказать, как закрыть gnuplot, окна псевдоконсолей и окно редактора. Все очень просто — и это тоже Unix-way! Запоминайте — в тех средах, которые принимают команды с клавиатуры, комбинация Ctrl-D означает «конец всему!». Иначе говоря, больше ничего с клавиатуры поступать не будет. Можно сворачивать работу и валить домой. Ну, по другому еще — это есть конец файла.

Поэтому, в gnuplot и в окне псевдоконсоли тупо жмите Ctrl-D и у они будут закрываться.

Текстовый редактор gedit — это полноценное оконное (а не консольное) приложение. Тут правило несколько другое. Для закрытия оконных приложений нужно нажимать Alt-F4. И не забывайте про Alt-Tab, если есть необходимость переключится на какое-нибудь окно.

И пожалуй скажу еще пару фраз — не бойтесь задавать вопросы. Не бойтесь показаться незнайками. Я всем говорю и сейчас повторю свою любимую фразу — не важно где ты сейчас находишься, важно — куда ты идешь. Задавая вопросы, вы продвигаетесь вперед в своем развитии. А это куда более важно, чем сиюминутная оплошность при глупом вопросе. Вопросы в принципе не могут быть глупыми!

Реклама

4 responses to “Работа в Линуксе и Фурье-преобразования

  1. Пара замечаний-комментариев:
    1. Лицо тётеньки можно найти не сразу. Стоило бы упомянуть, что она лежит лицом вверх 🙂
    2. Хорошо бы входной массив данных harm_t harm_ar не делать частью самой программы, а получать извне, например, из текстового файла.

    • Замечания принимаются.

      1. Да. Наверно следует присовокупить фотографию страницы из учебника. Там морда тетки нарисована в вертикальном положении, а профиль морды — аж дважды! И оба раза неправильно (с точки зрения правильного расположения графиков). Хотя, если в детстве играли в игру «на что походит облако» (или угадывали, на что походит раздавленная между листочками бумаги капля краски), то развитая фантазия должна подсказать.

      2. Тоже — да. Хорошо бы. Но есть одно маленькое «но». Хотелось бы сделать программу не «как правильно» (по-профессиональному), а как можно проще. Даже в ущерб стилю программирования. Да и комментарии бы не мешало бы наверно навешать на непонятные действия.

      Спасибо за советы. Возможно как-нибудь соберусь и подправлю публикацию, согласно Вашим замечаниям.

  2. А учебник физики (Мякишев. «Физика. Колебания и волны. Учебник для углубленного изучения) какого года издания?
    По-моему, современные учебные и пособия программа не очень-то способствуют получению фундаментальных знаний (разве что вопреки).
    Только и остаётся держаться за старую добрую советскую литературу.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s