Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Поиск точки в массиве  (Прочитано 9517 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Sergey Andriyanov
Новенький

ru
Offline Offline

« : 26-01-2016 14:18 » 

Здравствуйте. Нужна помощь,консультация.
Столкнулся с проблемой в вычислениях. Проблема: не могу придумать алгоритм поиска точки. Буду благодарен за любую помощь.
Есть прибор который измеряет фазу двух сигналов 45Мгц и 3Мгц. Фаза сигнала 45Мгц на дистанции 30 метров проходит 10 раз от 0 до 360 гр. Фаза сигнала 3Мгц через 50 метров. Фаза сигнала 3Мгц сильно зашумлена и нужна только для определения множителя i; ph_long = ph45Mhz+360*i
Результаты измерения в файле excel в нем 1500 точек снятых с шагом 20мм. В первой колонке: расстояние, в второй колонке: фаза 3Мгц, в третей: Фаза 45Мгц, в четвертой: непрерывная фаза вычисленная по такому алгоритму,этот алгоритм не очень нравиться а что то другое не получается придумать(
Код:


if ((phase3Mhz_deg > 33000) || (phase3Mhz_deg < 300)) {
coefmux = 1;
} else if ((phase3Mhz_deg >= 300) && (phase3Mhz_deg < 1100)) {
if (phase45Mhz_deg > 18000) {
coefmux = 1;
} else {
coefmux = 2;
}
} else if ((phase3Mhz_deg >= 1100) && (phase3Mhz_deg < 3100)) {
coefmux = 2;
} else if ((phase3Mhz_deg >= 3100) && (phase3Mhz_deg < 4100)) {
if (phase45Mhz_deg > 18000) {
coefmux = 2;
} else {
coefmux = 3;
}
} else if ((phase3Mhz_deg >= 4100) && (phase3Mhz_deg < 5100)) {
coefmux = 3;
} else if ((phase3Mhz_deg >= 5100) && (phase3Mhz_deg < 6400)) {
if (phase45Mhz_deg > 18000) {
coefmux = 3;
} else {
coefmux = 4;
}
} else if ((phase3Mhz_deg >= 6400) && (phase3Mhz_deg < 8300)) {
coefmux = 4;
} else if ((phase3Mhz_deg >= 8300) && (phase3Mhz_deg < 8900)) {
if (phase45Mhz_deg > 18000) {
coefmux = 4;
} else {
coefmux = 5;
}
} else if ((phase3Mhz_deg >= 8900) && (phase3Mhz_deg < 10700)) {
coefmux = 5;
} else if ((phase3Mhz_deg >= 10700) && (phase3Mhz_deg < 11500)) {
if (phase45Mhz_deg > 18000) {
coefmux = 5;
} else {
coefmux = 6;
}
} else if ((phase3Mhz_deg >= 11500) && (phase3Mhz_deg < 13000)) {
coefmux = 6;
} else if ((phase3Mhz_deg >= 13000) && (phase3Mhz_deg < 14000)) {
if (phase45Mhz_deg > 18000) {
coefmux = 6;
} else {
coefmux = 7;
}
} else if ((phase3Mhz_deg >= 14000) && (phase3Mhz_deg < 15500)) {
coefmux = 7;
} else if ((phase3Mhz_deg >= 15500) && (phase3Mhz_deg < 16500)) {
if (phase45Mhz_deg > 18000) {
coefmux = 7;
} else {
coefmux = 8;
}
} else if ((phase3Mhz_deg >= 16500) && (phase3Mhz_deg < 18000)) {
coefmux = 8;
} else if ((phase3Mhz_deg >= 18000) && (phase3Mhz_deg < 19300)) {
if (phase45Mhz_deg > 18000) {
coefmux = 8;
} else {
coefmux = 9;
}
} else if ((phase3Mhz_deg >= 19300) && (phase3Mhz_deg < 20400)) {
coefmux = 9;
} else if ((phase3Mhz_deg >= 20400) && (phase3Mhz_deg < 21700)) {
if (phase45Mhz_deg > 18000) {
coefmux = 9;
} else {
coefmux = 10;
}
} else if ((phase3Mhz_deg >= 21700) && (phase3Mhz_deg < 23000)) {
coefmux = 10;
} else if ((phase3Mhz_deg >= 23000) && (phase3Mhz_deg < 24500)) {
if (phase45Mhz_deg > 18000) {
coefmux = 10;
} else {
coefmux = 11;
}
} else if ((phase3Mhz_deg >= 24500) && (phase3Mhz_deg < 26500)) {
coefmux = 11;
} else {
coefmux = 0;
}
tempdouble = 36000.0 * (coefmux - 1.0) + phase45Mhz_deg;
ph_long = floor(tempdouble);

В расчетах все умножено на 100 . 360 градусов это 36000
В фале два графика в одном фазы в другом результат вычисленный по этому алгоритму.


* 30000_20mm_result.zip (45.05 Кб - загружено 890 раз.)
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 26-01-2016 23:00 » 

В чем именно состоит проблема? Громоздкий и плохо читаемый код?

Предлагаю избавиться от "магических" констант в коде и вынести их в древовидную структуру. Заводим структурный тип с полями:

  • нижняя граница диапазона;
  • верхняя граница диапазона;
  • значение коэффициента для phase45Mhz_deg > 18000;
  • значение коэффициента для phase45Mhz_deg <= 18000;
  • ссылка либо указатель на структуру для меньшего диапазона;
  • ссылка либо указатель на структуру для большего диапазона.

Кстати, можно сразу хранить коэффициент на единицу меньше, чтобы потом ее не вычитать; само собой, и на 36000 тоже можно заранее умножить.

После такого преобразования код должен стать намного компактнее и аккуратнее. Само собой, двоичное дерево надлежит сбалансировать.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Sergey Andriyanov
Новенький

ru
Offline Offline

« Ответ #2 : 27-01-2016 09:21 » 

Цитата
В чем именно состоит проблема? Громоздкий и плохо читаемый код?
Написано некрасиво. После измерения  неудобно задавать коэффициенты, можно запутаться. Благодарю, попробую оформить как вы предложили.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 27-01-2016 09:41 » 

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

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 27-01-2016 13:16 » 

Вот так оно получше будет:

Код: (C)
#include "findpoint.h"

typedef struct
{
        int phase3Mhz;
        int coefmux[2];
} TableItem;

static TableItem table[] =
{
        {     0,        {  1,  1 } },   //  0
        {   300,        {  2,  1 } },   //  1
        {  1100,        {  2,  2 } },   //  2
        {  3100,        {  3,  2 } },   //  3
        {  4100,        {  3,  3 } },   //  4
        {  5100,        {  4,  3 } },   //  5
        {  6400,        {  4,  4 } },   //  6
        {  8300,        {  5,  4 } },   //  7
        {  8900,        {  5,  5 } },   //  8
        { 10700,        {  6,  5 } },   //  9
        { 11500,        {  6,  6 } },   // 10
        { 13000,        {  7,  6 } },   // 11
        { 14000,        {  7,  7 } },   // 12
        { 15500,        {  8,  7 } },   // 13
        { 16500,        {  8,  8 } },   // 14
        { 18000,        {  9,  8 } },   // 15
        { 19300,        {  9,  9 } },   // 16  
        { 20400,        { 10,  9 } },   // 17
        { 21700,        { 10, 10 } },   // 18
        { 23000,        { 11, 10 } },   // 19
        { 24500,        { 11, 11 } },   // 20
        { 33000,        {  1,  1 } },   // 21
        { 36000,        {  0,  0 } }    // 22
};

static int lookup(int phase3Mhz_deg, int phase45Mhz_deg)
{
        int top = 0;
        int bottom = sizeof table / sizeof table[0] - 2;
        int middle;

        do
        {
                middle = (top + bottom) / 2;
                if (phase3Mhz_deg < table[middle].phase3Mhz)
                {
                        bottom = middle - 1;
                }
                else if (phase3Mhz_deg >= table[middle + 1].phase3Mhz)
                {
                        top = middle + 1;
                }
        } while (!((phase3Mhz_deg >= table[middle].phase3Mhz) && (phase3Mhz_deg < table[middle + 1].phase3Mhz)));

        return table[middle].coefmux[(int)(phase45Mhz_deg > 18000)];
}

extern long findpoint(int phase3Mhz_deg, int phase45Mhz_deg)
{
        int coefmux = lookup(phase3Mhz_deg, phase45Mhz_deg);

        return coefmux;
}
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Sergey Andriyanov
Новенький

ru
Offline Offline

« Ответ #5 : 30-01-2016 16:44 » 

Благодарю.   Попробую так действительно будет удобнее инициализировать а то я уже запутался. 
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines