Библиотека Generic классов - ошибки, описание, вопросы, особенности использования и предложения - страница 28

 
Alexey Volchanskiy:

Что за хрень тут опять твориться? Удаляют вполне адекватные посты по теме LinkedList. Так и представляю, сидит где-нибудь в Европе модер-анонимус и удаляет, злобно хихикая, посты у ненавистных русских. Помойка какая-то, пропадает желание писать.

Хорош воевать с мельницами - нет удалённых постов из этой ветки.

 
Artyom Trishkin:

Хорош воевать с мельницами - нет удалённых постов из этой ветки.

Артем, я не пьян и не под веществами. Я пол-часа назад написал короткий ответ, что в MQL LinkedList реализован, как именно кольцевой буфер и описанное поведение как раз нормально. И что я своих фильтрах делаю кольцевой буфер на обычном массиве. Потом полез в исходники .NET посмотреть реализацию, а через пол-часа мой мессадж удалили. Да в первый раз, что ли. 

На русских модераторов я как раз не думаю.

Вот класс фильтра с КИХ, смотреть функцию double  FilterTick(double tick). Там как раз два кольцевых буфера - входных тиков и выходных отфильтрованных значений. Разница с linked list в том, что меньше возможностей, зато на порядок быстрее, что мне важно. 

#ifndef Filter
#define Filter

//+------------------------------------------------------------------+
//|                                                       Filter.mqh |
//|                                               Alexey Volchanskiy |
//|                                      https://mql4.wordpress.com/ |
//+------------------------------------------------------------------+
#property copyright "Alexey Volchanskiy"
#property link      "https://mql4.wordpress.com/"
#property version   "1.04"
#property strict
#include <Object.mqh>
#include <AvLib-4-5\coeff.mqh>
#include <AvLib-4-5\Errors.mqh>

/*
Формат массива или файла коэффициентов фильтра
double coeff[] = {FiltersCount, FilterAddr, FilterLen, FilterAddr, FilterLen..., coeff1, coeff2, coeff3...};
*/
enum EErrors {EOk, ENumFilterOutOfRange};

class CFilter : CObject
{
#define TICK_BUF_SIZE       0x1000              // 4096
#define TICK_BUF_MAX_IDX    (TICK_BUF_SIZE - 1) // 0xFFF
#define OUT_BUF_SIZE        0x10000             // 65536
#define OUT_BUF_MAX_IDX     (OUT_BUF_SIZE - 1)  // 0xFFFF   

private:
    double  TickBuf[TICK_BUF_SIZE]; // промежуточный кольцевой буфер для хранения тиков
    double  OutBuf[OUT_BUF_SIZE];   // выходной кольцевой буфер
    double  Coeff[];                // массив коэффициентов
    int     TickBufIdx;             // индекс для нового входящего тика в TickBuf
    int     OutBufIdx;              // индекс для выходного буфера 
public:
    enum Errors {OK, NUM_FILTER_OUT_OF_RANGE };  
public:
    CFilter() {}
    ~CFilter() 
    {
        ArrayFree(Coeff);
    }
    
    double  GetOutBuf(const int idx)
    {
        int tmp = OutBufIdx-idx-1;
        double out = tmp >= 0 ? OutBuf[tmp] : OutBuf[OUT_BUF_SIZE+(tmp)]; 
        return out;
    }

    void    Init()
    {
        TickBufIdx = TICK_BUF_MAX_IDX;
        OutBufIdx = 0;
        for(int n = 0; n < TICK_BUF_SIZE; n++)
            TickBuf[n] = 0;
        for(int n = 0; n < OUT_BUF_SIZE; n++)
            OutBuf[n] = 0;
    }        

    EErrors  LoadCoeffFromArray(int numFilter, double &coeffArray[])
    {
        if(numFilter >= coeffArray[0])  // количество фильтров в массиве
            return ENumFilterOutOfRange;
        uint addr = (uint)coeffArray[1 + numFilter * 2];
        uint len = (uint)coeffArray[2 + numFilter * 2];   
        ArrayResize(Coeff, len);
        for(uint n = 0; n < len; n++)
            Coeff[n] = coeffArray[addr++];
        Init();    
        return EOk;
    }

    void    LoadCoeffFromArray(double &coeffArray[])
    {
        int len = ArraySize(coeffArray); 
        ArrayResize(Coeff, len);
        for(int n = 0; n < len; n++)
            Coeff[n] = coeffArray[n];
        Init();    
    }
    
    bool    LoadCoeffFromFile(int numFilter, string fileName)
    {
        // не реализовано
        return true;
    }
    
    // фильтрация одного тика
    double  FilterTick(double tick)
    {
        TickBuf[TickBufIdx] = tick;
        if (TickBufIdx == 0)
            TickBufIdx = TICK_BUF_MAX_IDX;
        else
            TickBufIdx--;
        int asize = ArraySize(Coeff); // вынести из функции!!!
        double acc = 0;
        int tbIdx = TickBufIdx;
        // делаем фильтрацию в цикле for
        for (int n = 0; n < asize; n++)
        {
            tbIdx++;
            /* вместо
            if(tbIdx > TICK_BUF_MAX_IDX)
            tbIdx = 0;
            */
            tbIdx &= TICK_BUF_MAX_IDX; // небольшая оптимизация вместо if
            acc += TickBuf[tbIdx] * Coeff[n];
        }
        OutBuf[OutBufIdx] = acc;
        OutBufIdx++;
        OutBufIdx &= OUT_BUF_MAX_IDX;
        return acc;
    }
    
    // фильтрация массива
    void    FilterTickSeries(double &ticks[], int count)
    {
        for(int n = 0; n < count; n++)
            ticks[n] = FilterTick(ticks[n]);
    }
};
#endif
 
Alexey Volchanskiy:

Артем, я не пьян и не под веществами. Я пол-часа назад написал короткий ответ, что в MQL LinkedList реализован, как именно кольцевой буфер и описанное поведение как раз нормально. И что я своих фильтрах делаю кольцевой буфер на обычном массиве. Потом полез в исходники .NET посмотреть реализацию, а через пол-часа мой мессадж удалили. Да в первый раз, что ли. 

На русских модераторов я как раз не думаю.

Вот класс фильтра с КИХ, смотреть функцию double  FilterTick(double tick). Там как раз два кольцевых буфера - входных тиков и выходных отфильтрованных значений. Разница с linked list в том, что меньше возможностей, зато на порядок быстрее, что мне важно. 

Ну не знаю - просмотрел удалённые посты - нет из этой ветки ничего. Шайтан ...

Мне тоже кажется логичным, что "связанный список" - он и есть связанный список. Простой список не имеет закольцовки, и работает как и говорил Алексей Навойков: "Next последнего узла равен нулю, так же как и  Previous начального", а связанный список - имеет, и работает как кольцевой буфер. Что по мне - удобно.

 
Artyom Trishkin:

Ну не знаю - просмотрел удалённые посты - нет из этой ветки ничего. Шайтан ...

Мне тоже кажется логичным, что "связанный список" - он и есть связанный список. Простой список не имеет закольцовки, и работает как и говорил Алексей Навойков: "Next последнего узла равен нулю, так же как и  Previous начального", а связанный список - имеет, и работает как кольцевой буфер. Что по мне - удобно.

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

 
Alexey Volchanskiy:

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

Вот, вот, внимательнее нужно быть, кнопки все положенные аккуратно жмакать.

 
Artyom Trishkin:

Мне тоже кажется логичным, что "связанный список" - он и есть связанный список. Простой список не имеет закольцовки, и работает как и говорил Алексей Навойков: "Next последнего узла равен нулю, так же как и  Previous начального", а связанный список - имеет, и работает как кольцевой буфер. Что по мне - удобно.

Связанный список - это список, хранящий указатели на следующий и предыдущий элементы. "Кольцевание" тут ни при чём. И вообще это что-то новое. Где такое видано?

Alexey Volchanskiy:
Вот класс фильтра с КИХ, смотреть функцию double  FilterTick(double tick). Там как раз два кольцевых буфера - входных тиков и выходных отфильтрованных значений. Разница с linked list в том, что меньше возможностей, зато на порядок быстрее, что мне важно. 

Да при чём здесь класс фильтра...  Мы ж говорим конкретно о связанном списке. Это стандартный контейнер, обладающий определёнными свойствами. Итерация по списку производится однонаправленно. Никакого кольцевания быть не может.  Ни в C# (идентичный класс LinkedList), ни в C++ (класс std::list)  нет такого.

Кроме того, данная библиотека портирована с .Net, предполагая совместимость с C#, иначе на кой чёрт нужен очередной самодельный велосипед?  Неужели не наелись ещё корявых велосипедов от MQ?  Всего-то требовалось - портировать готовую библиотеку (пусть и с ограничениями, присущими языку, но хотя бы чтобы логика работы сохранялась).  Но ведь нет же... Шаловливые ручёнки и тут вмешались )

Скорее всего, тот кто портировал эти классы, решил просто облегчить себе жизнь, упростив код.  Вместо двух указателей m_first и m_last сделал один указатель m_head…

Я то конечно себе всё подправил как надо.  Но тем не менее...

 
Alexey Navoykov:

Связанный список - это список, хранящий указатели на следующий и предыдущий элементы. "Кольцевание" тут ни при чём. И вообще это что-то новое. Где такое видано?

Да при чём здесь класс фильтра...  Мы ж говорим конкретно о связанном списке. Это стандартный контейнер, обладающий определёнными свойствами. Итерация по списку производится однонаправленно. Никакого кольцевания быть не может.  Ни в C# (идентичный класс LinkedList), ни в C++ (класс std::list)  нет такого.

Кроме того, данная библиотека портирована с .Net, предполагая совместимость с C#, иначе на кой чёрт нужен очередной самодельный велосипед?  Неужели не наелись ещё корявых велосипедов от MQ?  Всего-то требовалось - портировать готовую библиотеку (пусть и с ограничениями, присущими языку, но хотя бы чтобы логика работы сохранялась).  Но ведь нет же... Шаловливые ручёнки и тут вмешались )

Скорее всего, тот кто портировал эти классы, решил просто облегчить себе жизнь, упростив код.  Вместо двух указателей m_first и m_last сделал один указатель m_head…

Я то конечно себе всё подправил как надо.  Но тем не менее...

В MSDN его называют именно кольцевой буфер, я же не придумал название.

Главное, не правьте в папке Include, а то при апгрейде на новый билд МТ5 все затрется.

 
Vladimir Karputov:

Вот, вот, внимательнее нужно быть, кнопки все положенные аккуратно жмакать.

Вероятность такой возможности стремиться к нулю. А вот что у меня ветку на англоязычной ветке анонимно грохнули, это факт. ***

 
Alexey Volchanskiy:

Вероятность такой возможности стремиться к нулю. А вот что у меня ветку на англоязычной ветке анонимно грохнули, это факт. ***

Хватит уже про эту ветку. Ещё раз вспомнишь и выдам березовый веник. Надоел.

 
Alexey Volchanskiy:

Главное, не правьте в папке Include, а то при апгрейде на новый билд МТ5 все затрется.

У меня это в отдельной папке Generic_.  Там на самом деле ещё немало допиливать пришлось.  Начиная от проставления const для методов (разработчики не сочли это нужным),  и заканчивая переделкой под аргументы по ссылке, а не только по значению.

Причина обращения: