Bibliotecas: ALGLIB - Numerical Analysis Library - página 4

 
Yury Kulikov:

Linda MQ! Trabalho sério!

Um exemplo de uso da biblioteca é ensinar à rede neural MLP a tabuada.


:( Tenho medo de pensar no que acontecerá com a nuvem quando os usuários começarem a usar ativamente a biblioteca em seus especialistas.
Esse script simples pesa menos de um megabyte.


O mesmo, mas para RF:

não é tão preciso, devo tentar ajustá-lo

#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];
   
   // preparação de dados
   PatternsMatrix.Resize(100,3);
   int m=0;     // primeiro padrão
   for(int i=1; i<=10; i++)
      for(int j=1; j<=10; j++)
      {
         PatternsMatrix[m].Set(0,i/10.0);       // entrada 1
         PatternsMatrix[m].Set(1,j/10.0);       // entrada 2
         PatternsMatrix[m].Set(2,(i*j)/100.0);  // alvo
         m++; //próximo padrão
      }
   // Criação de RF.
   CDForest::DFBuildRandomDecisionForest(PatternsMatrix,100,2,1,50,0.4,RFinfo,Trf,RF_report);
   Print("Info=",RFinfo,"  Error=",CDForest::DFAvgError(Trf,PatternsMatrix,100));  
   // verificar a rede em dados inteiros
   string s="Teste 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);
   // verificar a rede em dados fracionários
   s="Teste 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);

é mais preciso, 500 antigos e r=1, mais ajuste e menos ruído.

2017.09.04 22:08:33.227 RF sample (EURUSD,H1)   Info=1  Error=2.02997341158806 e-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:


A mesma coisa para RF:

Considera que não é tão preciso, precisa tentar ajustá-lo

PS

essa maneira é mais precisa, 500 árvores e r=1, mais ajuste e menos ruído.

Gostaria de saber quantas árvores você precisa fazer para que os resultados sejam precisos? E é a tabela de multiplicação mais simples e, se houver várias funções, precisamos executar a RF e não a tabela de multiplicação, então a resposta obviamente se assemelhará a algo justo de longe?
 
A biblioteca MQL5 é, de fato, muito poderosa; veja como chamar a biblioteca em mais detalhes
 

Obrigado @Rashid Umarov

Recomendo a todos que acessem o site, porque este tópico foi atualizado por 3 anos, mas o site continua sendo atualizado.

 

Fizemos uma revisão completa da versão baseada em GPL C++ da biblioteca ALGLIB, lançando-a como ALGLIB++. Isso rastreia a versão mais recente do ALGLIB, que está na versão 3.16.0, a partir de 12 de 2019. Muito foi adicionado nos módulos de otimização e interpolação desde as versões anteriores com as quais a MQL5 está sincronizada (por exemplo, splines de nuvem de pontos(!), mais métodos de interpolação ponderada de distância inversa, vários métodos de otimização adicionais etc.).

O ALGLIB++ é um derivado do ALGLIB que está sendo usado como uma forma intermediária em um processo de reengenharia/refatoração de longo prazo, no qual será recodificado em C++ nativo (semelhante ao que era antes da Versão 3), a camada extra e a duplicação sendo removidas em preparação para fornecer suporte mais direto a multi-threading, bem como testes e módulos adicionais e, eventualmente, um front-end de linguagem de script.

As diferentes versões de linguagem do ALGLIB foram todas geradas a partir de um núcleo comum, com a versão C++ fornecendo suporte limitado (mas não oficial) para o dialeto C90 do C. Esse recurso tornou necessário simular, dentro do C, recursos que, de outra forma, seriam nativos do C++ e, em seguida, fornecer um wrapper C++ sobre isso. Da mesma forma, há dois espaços de nomes separados: alglib_impl, que contém a versão em C, e alglib, que contém os wrappers em C++. O ALGLIB++ manteve a maior parte dessa estrutura e o máximo possível da codificação original, mas reduziu ou eliminou grande parte da infraestrutura global como uma primeira etapa para sua eliminação e substituição por código C++ nativo multi-threaded e simplificou significativamente a interface do wrapper C++. Dessa forma, ele representa uma ponte de forma intermediária entre o próprio ALGLIB e a futura biblioteca na qual o ALGLIB++ está sendo transformado.


Muitos problemas que levaram a um aumento de complexidade no ALGLIB, desde (e antes) das versões adaptadas pelo MQL5, foram resolvidos, com a consequente simplificação da estrutura e redução da complexidade. Em sua forma atual, deve ser mais fácil adaptar o ALGLIB à MQL5 por aqueles que estão atualmente mantendo a versão MQL5 do ALGLIB.

A distribuição inclui uma reformatação completa do manual do ALGLIB++ a partir do ALGLIB C++ original. As seções sobre os pacotes e subpacotes, no entanto, são compatíveis com ambas as versões do ALGLIB, e o layout e o conteúdo devem ser facilmente adaptados à versão MQL5. A MQL5 é mencionada na seção "References & Related Links" do manual.


A versão mais recente pode ser encontrada em para futura integração ao ALGLIB++. Outras bibliotecas, incluindo a MKL (que, a propósito, tem rotinas de redes neurais), também estão sendo consideradas para integração futura.

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
 
Algumas observações adicionais para os desenvolvedores da versão MQL5 do ALGLIB:

Quando você adaptou o ALGLIB para MQL5, teve dificuldades com as rotinas "RCOMM".

Essas rotinas são efetivamente multi-threaded, onde a troca de thread é escrita diretamente no código por meio de:
(1) armazenamento em cache de variáveis locais de thread a cada entrada e saída - e as rotinas de iteração executam potencialmente milhões e bilhões de ciclos de chamada/retorno!
(2) implementação de thread-switching saltando para fora da rotina para "pausar" em um evento e saltando de volta para a rotina para "retomar" após o evento - o que significa muitos goto's e vários pontos de entrada.
(3) reduzir a estrutura do fluxo de controle dessas rotinas para colocar os pontos de entrada no nível superior do corpo da função.

Ao adaptar o ALGLIB para a MQL5, você manteve a decimação do fluxo de controle, na verdade enviando os trechos de código para rotinas separadas. Essa solução - como você acabou descobrindo - não é passível de manutenção, o que tornou impossível acompanhar as atualizações do ALGLIB. O próprio ALGLIB também ficou um pouco para trás na curva - suas rotinas RCOMM às vezes deixam estruturas e variáveis órfãs de versões anteriores.

No ALGLIB++, a estrutura do fluxo de controle é reintegrada: os pontos de entrada voltam para o meio de um loop ou outra estrutura de fluxo de controle de onde pararam.
Não há armazenamento em cache de variáveis locais de thread; por enquanto, elas foram tornadas estáticas (ao custo da segurança de thread - mas o multi-threading não é formalmente uma parte do ALGLIB GPL).
Como no ALGLIB, isso significa que há muitas instruções goto para fazer todos os saltos para frente e para trás, mas elas são organizadas de forma mais limpa.
Os reparos feitos no ALGLIB++, por si só, aceleram as rotinas em cerca de 20 a 25%, com base nos resultados de nossos testes.

Há duas maneiras de lidar com essa arquitetura para se livrar das instruções goto e lidar mais adequadamente com as variáveis locais de thread:
(1) Implementar a troca de thread real, o que significa que as rotinas RCOMM enviam mensagens de "evento" (que é o que os sinalizadores needf, ... algpowerup realmente são), e o chamador precisa configurar um manipulador de eventos para receber e processar as mensagens. No entanto, não tenho certeza se a MQL5 pode produzir e manipular eventos definidos pelo usuário.
(2) Use ponteiros de função para os eventos.
Lembre-se de que as rotinas RCOMM podem ser aninhadas e, em alguns casos, elas podem retransmitir eventos para seu chamador, obtidos das rotinas RCOMM que elas mesmas chamam.

Os desenvolvedores do ALGLIB decidiram não usar ponteiros de função ou multi-threading quando implementaram o ALGLIB, porque quando o ALGLIB foi lançado pela primeira vez, não havia suporte formal para programação multi-threaded em nenhuma linguagem amplamente distribuída e amplamente usada, e nem todas as linguagens para as quais o ALGLIB foi direcionado tinham o mesmo equivalente ou similar aos ponteiros de função do C e do C++. Mas a MQL5 tem ponteiros de função. Se você adaptar o ALGLIB à MQL5, será muito mais fácil fazer isso a partir do ALGLIB++, devido à reintegração das estruturas de fluxo de controle.

No entanto, a solução ideal é usar o thread-switching. Eventualmente, tanto os ponteiros de função quanto o thread-switching serão usados no ALGLIB++; ainda não decidimos qual caminho seguir.

 
LydiaMW:
Algumas observações adicionais para os desenvolvedores da versão MQL5 do ALGLIB:

Quando você adaptou o ALGLIB para MQL5, teve dificuldades com as rotinas "RCOMM".

Essas rotinas são efetivamente multi-threaded, onde a troca de thread é escrita diretamente no código por:
(1) armazenamento em cache de variáveis locais de thread a cada entrada e saída - e as rotinas de iteração executam potencialmente milhões e bilhões de ciclos de chamada/retorno!
(2) implementação de thread-switching saltando para fora da rotina para "pausar" em um evento e saltando de volta para a rotina para "retomar" após o evento - o que significa muitos goto's e vários pontos de entrada.
(3) reduzir a estrutura do fluxo de controle dessas rotinas para colocar os pontos de entrada no nível superior do corpo da função.

Ao adaptar o ALGLIB para a MQL5, você manteve a decimação do fluxo de controle, na verdade enviando os trechos de código para rotinas separadas. Essa solução - como você acabou descobrindo - não é passível de manutenção, o que tornou impossível acompanhar as atualizações do ALGLIB. O próprio ALGLIB também ficou um pouco para trás na curva - suas rotinas RCOMM às vezes deixam estruturas e variáveis órfãs de versões anteriores.

No ALGLIB++, a estrutura do fluxo de controle é reintegrada: os pontos de entrada voltam para o meio de um loop ou outra estrutura de fluxo de controle de onde pararam.
Não há armazenamento em cache de variáveis locais de thread; por enquanto, elas foram tornadas estáticas (ao custo da segurança de thread - mas o multi-threading não é formalmente uma parte do ALGLIB GPL).
Como no ALGLIB, isso significa que há muitas instruções goto para fazer todos os saltos para frente e para trás, mas elas são organizadas de forma mais limpa.
Os reparos feitos no ALGLIB++, por si só, aceleram as rotinas em cerca de 20 a 25%, com base nos resultados de nossos testes.

Há duas maneiras de lidar com essa arquitetura para se livrar das instruções goto e lidar mais adequadamente com as variáveis locais de thread:
(1) Implementar a troca de thread real, o que significa que as rotinas RCOMM enviam mensagens de "evento" (que é o que os sinalizadores needf, ... algpowerup realmente são), e o chamador precisa configurar um manipulador de eventos para receber e processar as mensagens. No entanto, não tenho certeza se a MQL5 pode produzir e manipular eventos definidos pelo usuário.
(2) Use ponteiros de função para os eventos.
Lembre-se de que as rotinas RCOMM podem ser aninhadas e, em alguns casos, elas podem retransmitir eventos para seu chamador obtidos das rotinas RCOMM que elas mesmas chamam.

Os desenvolvedores do ALGLIB decidiram não usar ponteiros de função ou multi-threading quando implementaram o ALGLIB, porque quando o ALGLIB foi lançado pela primeira vez, não havia suporte formal para programação multi-threaded em nenhuma linguagem amplamente distribuída e amplamente usada, e nem todas as linguagens para as quais o ALGLIB foi direcionado tinham o mesmo equivalente ou similar aos ponteiros de função do C e do C++. Mas a MQL5 tem ponteiros de função. Se você adaptar o ALGLIB à MQL5, será muito mais fácil fazer isso a partir do ALGLIB++, devido à reintegração das estruturas de fluxo de controle.

No entanto, a solução ideal é usar o thread-switching. Eventualmente, tanto os ponteiros de função quanto o thread-switching serão usados no ALGLIB++; ainda não decidimos qual caminho seguir.

Prezada Lydia:

Mas seu arquivo de biblioteca ALGLIB ++ no github ainda está no formato C ++ CPP. Ele não foi convertido para MQL5 mql. Você poderia fornecer o arquivo da biblioteca ALGLIB ++ como .mql? Obrigado!

 

Caros desenvolvedores, adicionem um método para calcular o número conjugado de umnúmero complexo à estrutura complexa ( fonte em SB <Math\Alglib\complex.mqh>).

Minha versão:

   //--- operações
   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;


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


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


Após a próxima versão de uma nova compilação, você precisa reverter para arevisão anterior. O que é inconveniente.

 
Denis Kirichenko:

Caros desenvolvedores, adicionem um método de cálculo do número conjugado de umnúmero complexo à estrutura complexa ( fonte em SB <Math\Alglib\complex.mqh>).

Minha versão:


Após a próxima versão de uma nova compilação, você precisa reverter para arevisão anterior. O que é inconveniente.

Adicionado