Библиотеки: ALGLIB - библиотека численного анализа - страница 4

[Удален]  
Yury Kulikov:

Красавцы MQ! Серьезная работа!

Пример использования библиотеки - обучение нейронной сети MLP таблице умножения.


:( Вот только боюсь подумать, что будет с облаком, когда пользователи начнут активно использовать библиотеку в своих экспертах.
Данный простой скрипт весит под мегабайт.


То же но для RF:

считает не так точно, надо попробовать подтюнить

#include <Math\Alglib\dataanalysis.mqh>
//+------------------------------------------------------------------+
#define _rand(min,max) ((rand()/(double)SHORT_MAX)*((max)-(min))+min)
//+------------------------------------------------------------------+
void OnStart()
{
   CDecisionForest      Trf;
   CDecisionForestShell RFshell;
   CMatrixDouble        PatternsMatrix;
   CDFReport            RF_report;
   int RFinfo;
   double vector[2], out[1];
   
   // подготовка данных
   PatternsMatrix.Resize(100,3);
   int m=0;     // first pattern
   for(int i=1; i<=10; i++)
      for(int j=1; j<=10; j++)
      {
         PatternsMatrix[m].Set(0,i/10.0);       // input 1
         PatternsMatrix[m].Set(1,j/10.0);       // input 2
         PatternsMatrix[m].Set(2,(i*j)/100.0);  // target
         m++; //next pattern
      }
   // создание RF
   CDForest::DFBuildRandomDecisionForest(PatternsMatrix,100,2,1,50,0.4,RFinfo,Trf,RF_report);
   Print("Info=",RFinfo,"  Error=",CDForest::DFAvgError(Trf,PatternsMatrix,100));  
   // проверка сети на целочисленных данных
   string s="Тест 1 >> ";
   for(int i=1; i<=10; i++)
   {
      int d1=(int)_rand(1,10), d2=(int)_rand(1,10);
      vector[0]=d1/10.0;
      vector[1]=d2/10.0;
      CDForest::DFProcess(Trf,vector,out);
      s+=(string)d1+"*"+(string)d2+"="+DoubleToString(out[0]*100,0)+" // ";
   }
   Print(s);
   // проверка сети на дробныx данных
   s="Тест 2 >> ";
   for(int i=1; i<=5; i++)
   {
      double d1=NormalizeDouble(_rand(1,10),1), d2=NormalizeDouble(_rand(1,10),1);
      vector[0]=d1/10.0;
      vector[1]=d2/10.0;
       CDForest::DFProcess(Trf,vector,out);
      s+=DoubleToString(d1,1)+"*"+DoubleToString(d2,1)+"="+DoubleToString(out[0]*100,2)+
         "("+DoubleToString(d1*d2,2)+") // ";
   }
   Print(s);
}
2017.09.04 21:43:21.609 RF sample (EURUSD,H1)   Info=1  Error=0.01861400000000001
2017.09.04 21:43:21.610 RF sample (EURUSD,H1)   Тест 1 >> 6*9=55 // 7*3=21 // 6*6=38 // 9*7=65 // 9*9=80 // 8*4=32 // 4*1=6 // 1*8=13 // 4*3=12 // 2*2=5 // 
2017.09.04 21:43:21.610 RF sample (EURUSD,H1)   Тест 2 >> 7.7*5.8=46.64(44.66) // 3.0*3.3=9.70(9.90) // 6.0*9.2=55.32(55.20) // 2.6*6.7=20.08(17.42) // 2.5*4.0=12.54(10.00) // 

PS 

CDForest::DFBuildRandomDecisionForest(PatternsMatrix,100,2,1,500,1,RFinfo,Trf,RF_report);

так точнее, 500 древ и r=1, бОльшая подгонка и меньше шума

2017.09.04 22:08:33.227 RF sample (EURUSD,H1)   Info=1  Error=2.02997341158806e-15
2017.09.04 22:08:33.228 RF sample (EURUSD,H1)   Тест 1 >> 2*2=4 // 2*6=12 // 1*9=9 // 9*1=9 // 4*7=28 // 9*6=54 // 5*6=30 // 5*5=25 // 4*1=4 // 1*4=4 // 
2017.09.04 22:08:33.230 RF sample (EURUSD,H1)   Тест 2 >> 4.0*3.8=16.00(15.20) // 9.6*3.1=30.00(29.76) // 5.5*6.4=36.00(35.20) // 4.0*4.4=16.00(17.60) // 1.6*4.2=8.00(6.72) // 
 
Maxim Dmitrievsky:


То же но для RF:

считает не так точно, надо попробовать подтюнить

PS 

так точнее, 500 древ и r=1, бОльшая подгонка и меньше шума

Интересно, это сколько деревьев нужно сделать чтобы результаты ответа были точными? А ведь это простейшая таблица умножения, а если фукций несколько то нужно прогнать по РФ а не таблицу умножения, то ответ очевидно вообще будет издалека напоминать чтото справедливое?
 
Библиотека MQL5 действительно очень мощная, подробнее о том, как вызвать библиотеку
 

Спасибо @Rashid Umarov

Я рекомендую всем зайти на сайт, потому что эта тема обновляется уже 3 года, но сайт продолжает обновляться.

 

Мы полностью переработали GPL C++ версию библиотеки ALGLIB, выпустив ее под названием ALGLIB++. Это отслеживает последнюю версию ALGLIB, которая по состоянию на 2019/12 находится в версии 3.16.0. В модули оптимизации и интерполяции было добавлено много нового по сравнению с предыдущими версиями, с которыми синхронизирован MQL5 (например, сплайны с точечными облаками(!), больше методов интерполяции с обратным взвешенным расстоянием, множество дополнительных методов оптимизации и т.д.).

ALGLIB++ - это производная ALGLIB, которая используется в качестве промежуточной формы в долгосрочном процессе реинжиниринга/рефакторинга, в ходе которого она будет перекодирована на родной C++ (аналогично тому, как это было до версии 3), лишние слои и дублирование будут удалены для подготовки к обеспечению более прямой поддержки многопоточности, а также дополнительных тестов и модулей и, в конечном итоге, фронт-энда скриптового языка.

Различные языковые версии ALGLIB были созданы на основе общего ядра, при этом версия для C++ обеспечивала ограниченную (но неофициальную) поддержку диалекта C90 языка C. Эта особенность сделала необходимым имитировать в рамках C возможности, которые в противном случае были бы присущи C++, а затем предоставить обертку C++ поверх этого. Соответственно, существует два отдельных пространства имен: alglib_impl, содержащее версию на Си, и alglib, содержащее обертки на Си++. ALGLIB++ сохранил большую часть этой структуры и как можно больше оригинального кодирования, но сократил или устранил большую часть глобальной инфраструктуры в качестве первого шага для ее устранения и замены многопоточным нативным кодом C++ и значительно упростил интерфейс обертки C++. Как таковая, она представляет собой промежуточную форму, соединяющую ALGLIB как таковой и будущую библиотеку, в которую превращается ALGLIB++.


Многие проблемы, которые привели к росту сложности ALGLIB, начиная с версий, адаптированных под MQL5 (и до них), были решены, что привело к упрощению структуры и снижению сложности. В своем нынешнем виде он должен оказаться проще в адаптации к MQL5 для тех, кто в настоящее время поддерживает MQL5-версию ALGLIB.

В дистрибутив включено полное переформатирование руководства для ALGLIB++ с оригинала ALGLIB C++. Однако разделы, посвященные пакетам и подпакетам, совместимы с обеими версиями ALGLIB, и их расположение и содержание должны быть легко адаптированы к версии MQL5. MQL5 упоминается в разделе руководства "Ссылки и сопутствующие материалы".


Последнюю версию можно найти по адресу для будущей интеграции в ALGLIB++. Другие библиотеки, включая MKL (в которой, кстати, есть подпрограммы для нейронных сетей), также рассматриваются для будущей интеграции.

LydiaMarieWilliamson/ALGLIB_cpp
LydiaMarieWilliamson/ALGLIB_cpp
  • LydiaMarieWilliamson
  • github.com
Dismiss Join GitHub today GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together. Sign up Permalink
 
Несколько дополнительных замечаний разработчикам MQL5-версии ALGLIB:

Когда вы адаптировали ALGLIB к MQL5, вы столкнулись с трудностями в работе с подпрограммами "RCOMM".

Это фактически многопоточные подпрограммы, где переключение потоков происходит непосредственно в коде за счет:
(1) кэширования локальных переменных потока при каждом входе и выходе - а итерационные процедуры выполняют потенциально миллионы и миллиарды циклов вызова/возврата!
(2) реализации переключения потоков путем выпрыгивания из рутины для "паузы" по событию и возвращения в рутину для "возобновления" после события - что означает множество goto и множественные точки входа.
(3) сокращение структуры потока управления этих процедур, чтобы поместить точки входа на верхний уровень в теле функции.

При адаптации ALGLIB к MQL5 вы сохранили децимацию потока управления, фактически вынеся фрагменты кода в отдельные подпрограммы. Это решение - как вы в конце концов обнаружили - не поддерживается; что сделало невозможным поддержание обновлений ALGLIB. Сам ALGLIB тоже немного отстал от жизни - их RCOMM-программы иногда оставляют бесхозные структуры и переменные из ранних версий.

В ALGLIB++ структура потока управления реинтегрирована: точки входа возвращаются в середину цикла или другой структуры потока управления, где они остановились.
Кэширование переменных, локальных для потока, отсутствует; на данный момент они сделаны статическими (ценой потокобезопасности - но многопоточность формально не является частью GPL ALGLIB).
Как и в ALGLIB, это означает наличие большого количества операторов goto для выполнения всех переходов туда-сюда; но они организованы более чисто.
Исправления, сделанные в ALGLIB++, сами по себе ускоряют работу процедур примерно на 20-25 %, судя по результатам наших тестов.

Чтобы избавиться от операторов goto и более корректно работать с локальными переменными потоков, есть два пути решения проблемы с этой архитектурой:
(1) Реализовать фактическое переключение потоков, что означает, что процедуры RCOMM посылают "событийные" сообщения (чем, собственно, и являются флаги needf, ... algpowerup), а вызывающая сторона должна установить обработчик событий для получения и обработки этих сообщений. Однако не уверен, что MQL5 может создавать и обрабатывать пользовательские события.
(2) Использовать указатели функций для событий.
Следует помнить, что подпрограммы RCOMM могут быть вложенными, и в некоторых случаях они могут передавать вызывающему их пользователю события, полученные от подпрограмм RCOMM, которые они сами вызывают.

Разработчики ALGLIB решили не использовать указатели функций или многопоточность при реализации ALGLIB, поскольку на момент выпуска ALGLIB не было официальной поддержки многопоточного программирования ни в одном широко распространенном и широко используемом языке, и не все языки, на которые был ориентирован ALGLIB, имели такой же или подобный эквивалент указателей функций в C и C++. Но в MQL5 указатели функций есть. Если вы адаптируете АЛГЛИБ к MQL5, то из-за реинтеграции структур потока управления сделать это из АЛГЛИБ++ будет гораздо проще.

Идеальным решением, однако, является использование переключения потоков. В конечном итоге в ALGLIB++ будут использоваться либо указатели функций, либо переключение потоков; мы еще не решили, какой путь выбрать.

 
LydiaMW:
Несколько дополнительных замечаний для разработчиков MQL5-версии ALGLIB:

Когда вы адаптировали ALGLIB к MQL5, то столкнулись с трудностями в работе с подпрограммой "RCOMM".

Это фактически многопоточные процедуры, где переключение потоков записано непосредственно в коде:
(1) кэширования локальных переменных потока при каждом входе и выходе - и итерационные подпрограммы выполняют потенциально миллионы и миллиарды циклов вызова/возврата!
(2) реализации переключения потоков путем выпрыгивания из рутины для "паузы" по событию и возвращения в рутину для "возобновления" после события - что означает множество goto и множество точек входа.
(3) Уменьшение структуры потока управления этих процедур, чтобы поместить точки входа на верхний уровень в теле функции.

При адаптации ALGLIB к MQL5 вы сохранили децимацию потока управления, фактически вынеся фрагменты кода в отдельные подпрограммы. Это решение - как вы в конце концов обнаружили - не поддерживается; что сделало невозможным поддержание обновлений ALGLIB. Сам ALGLIB тоже немного отстал от жизни - их RCOMM-рутины иногда оставляют бесхозные структуры и переменные из ранних версий.

В ALGLIB++ структура потока управления реинтегрирована: точки входа возвращаются в середину цикла или другой структуры потока управления, где они остановились.
Кэширование потоково-локальных переменных отсутствует; на данный момент они сделаны статическими (ценой потокобезопасности - но многопоточность формально не является частью GPL ALGLIB).
Как и в ALGLIB, это означает наличие большого количества операторов goto для выполнения всех переходов туда-сюда; но они организованы более чисто.
Исправления, сделанные в ALGLIB++, сами по себе ускоряют работу процедур примерно на 20-25 %, судя по результатам наших тестов.

Есть два способа справиться с этой архитектурой, чтобы избавиться от операторов goto и более корректно работать с локальными переменными потоков:
(1) Реализовать фактическое переключение потоков, что означает, что процедуры RCOMM посылают "событийные" сообщения (чем, собственно, и являются флаги needf, ... algpowerup), а вызывающая сторона должна установить обработчик событий для получения и обработки этих сообщений. Однако не уверен, что MQL5 может создавать и обрабатывать события, определяемые пользователем.
(2) Использовать указатели функций для событий.
Имейте в виду, что подпрограммы RCOMM могут быть вложенными; в некоторых случаях они могут передавать вызывающему их пользователю события, полученные от подпрограмм RCOMM, которые они сами вызывают.

Разработчики ALGLIB решили не использовать указатели функций или многопоточность при реализации ALGLIB, поскольку на момент выпуска ALGLIB не было формальной поддержки многопоточного программирования ни в одном широко распространенном и широко используемом языке, и не все языки, на которые был ориентирован ALGLIB, имели такой же или подобный эквивалент указателей функций в C и C++. Но в MQL5 указатели функций есть. Если вы адаптируете АЛГЛИБ к MQL5, вам будет гораздо проще сделать это из АЛГЛИБ++, так как структуры потока управления будут интегрированы.

Идеальным решением, однако, является использование переключения потоков. В конечном итоге в ALGLIB++ будут использоваться либо указатели функций, либо переключение потоков; мы еще не решили, какой путь выбрать.

Уважаемая Лидия:

Но ваш файл библиотеки ALGLIB++ на github все еще находится в формате C++ CPP. Он не был преобразован в MQL5 mql. Не могли бы вы предоставить файл библиотеки ALGLIB ++ в формате .mql? Спасибо!

 

Уважаемые разработчики, прошу добавить метод расчёта сопряженного числа комплексного числа в структуру complex (исходник в СБ <Math\Alglib\complex.mqh>)

Моя версия:

   //--- operations
   void              Copy(const complex &rhs);
   bool              Eq(const complex &lhs, const complex &rhs);
   bool              NotEq(const complex &lhs, const complex &rhs);
   complex           Add(const complex &lhs, const complex &rhs);
   complex           Sub(const complex &lhs, const complex &rhs);
   complex           Mul(const complex &lhs, const complex &rhs);
   complex           Div(const complex &lhs, const complex &rhs);
   complex           Conjugate(void) const;


................


//+------------------------------------------------------------------+
//| Conjugate                                                        |
//+------------------------------------------------------------------+
complex complex::Conjugate(void) const
  {
   complex complex_val(re,-im);
   return complex_val;
  };


После очередного релиза нового билда приходится откатывать к своей прежней ревизии. Что неудобно.

 
Denis Kirichenko:

Уважаемые разработчики, прошу добавить метод расчёта сопряженного числа комплексного числа в структуру complex (исходник в СБ <Math\Alglib\complex.mqh>)

Моя версия:


После очередного релиза нового билда приходится откатывать к своей прежней ревизии. Что неудобно.

Добавлено