English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
preview
MQL5'te matrisler ve vektörler

MQL5'te matrisler ve vektörler

MetaTrader 5Ticaret | 17 Şubat 2023, 08:53
591 0
MetaQuotes
MetaQuotes

Aynı türdeki sıralı veri koleksiyonlarıyla çalışmak için genellikle her elemana kendi indeksi aracılığıyla erişilebilen diziler kullanılır. Diziler, lineer cebir, matematiksel modelleme, makine öğrenimi vb. birçok problemin çözümünde yaygın olarak kullanılmaktadır. Genel anlamda, bu tür problemlerin çözümü, çok karmaşık dönüşümlerin basit formüller biçiminde kompakt bir şekilde yazılabileceği matrisler ve vektörler kullanılarak gerçekleştirilen matematiksel işlemlere dayanır. Bu tür işlemleri programlamak, yalnızca iyi düzeyde matematik bilgisi değil, aynı zamanda karmaşık iç içe döngüler yazma becerisi de gerektirir. Bu tür programlarda hata ayıklama ve düzeltme oldukça zor olabilir. 

matrix ve vector özel veri türleri, matematiksel gösterime çok yakın kodların oluşturulmasına olanak sağlar. Bu, programcıyı iç içe döngüler oluşturmaktan ve hesaplamaya dahil olan dizilerin sürekli olarak doğru bir şekilde indekslenmesine dikkat etmekten kurtarır. Bu makalede, MQL5'te matrix ve vector nesnelerinin nasıl oluşturulacağını, başlatılacağını ve kullanılacağını göreceğiz.


vector türü

Vektör, double türünde tek boyutlu bir dizidir. Vektörler üzerinde toplama ve çarpma işlemleri tanımlanmıştır ve vektörün uzunluğunu veya modülünü elde etmek için de norm kavramı kullanılır. Programlamada, vektörler genellikle, üzerinde sıradan vektör işlemlerinin gerçekleştirilemediği, yani dizilerin toplanamadığı veya çarpılamadığı ve ayrıca normları da olmayan homojen eleman dizileriyle temsil edilir.

Matematikte vektörler, satır vektörleri, yani bir satır ve n sütundan oluşan bir dizi ve sütun vektörleri, yani bir sütun ve n satırdan oluşan bir matris olarak temsil edilebilir. MQL5'te vector türünün satır ve sütun alt türleri yoktur, bu nedenle programcının belirli bir işlemi gerçekleştirirken hangi vektör türünün kullanıldığını bilmesi gerekir.

Yerleşik metotlar kullanılarak bir vektör oluşturabilir ve başlatılabilir.

Metot
NumPy analoğu
Açıklama
void vector.Init(ulong size);   Tanımlanmış hiçbir değer olmadan belirtilen uzunlukta bir vektör oluşturur
static vector vector::Ones(ulong size);
 ones
Birlerle dolu, belirtilen uzunlukta bir vektör oluşturur
static vector vector::Zeros(ulong size);
 zeros
Sıfırlarla dolu, belirtilen uzunlukta bir vektör oluşturur
static vector vector::Full(ulong size,double value);
 full
Belirtilen değerle dolu, belirtilen uzunlukta bir vektör oluşturur
operator =

Vektörün bir kopyasını geri döndürür
void vector.Resize(const vector v);
  Sonuna yeni değerler ekleyerek vektörü yeniden boyutlandırır 


Vektör oluşturma örnekleri:

void OnStart()
 {
//--- vector initialization examples
  vector v;
  v.Init(7);
  Print("v = ", v); 

  vector v1=vector::Ones(5);
  Print("v1 = ", v1);

  vector v2=vector::Zeros(3);
  Print("v2 = ", v2);

  vector v3=vector::Full(6, 2.5);
  Print("v3 = ", v3);

  vector v4{1, 2, 3};
  Print("v4 = ", v4);  
  v4.Resize(5);
  Print("after Resize(5) v4 = ", v4);  
  
  vector v5=v4;
  Print("v5 = ", v5);  
  v4.Fill(7);
  Print("v4 = ", v4, "   v5 =",v5);  
   
 }
 
 
/*
Execution result

v = [4,5,6,8,10,12,12]
v1 = [1,1,1,1,1]
v2 = [0,0,0]
v3 = [2.5,2.5,2.5,2.5,2.5,2.5]
v4 = [1,2,3]
after Resize(5) v4 = [1,2,3,7,7]
v5 = [1,2,3,7,7]
v4 = [7,7,7,7,7]   v5 =[1,2,3,7,7]

*/ 

Init metodu yalnızca vektöre bellek ayırmak için değil, aynı zamanda bir fonksiyon kullanarak vektör elemanlarını değerlerle başlatmak için de kullanılabilir. Bu durumda, vektörün büyüklüğü Init'e birinci parametre olarak, fonksiyonun adı da ikinci parametre olarak iletilir. Fonksiyon parametreler içeriyorsa, bu parametreler fonksiyonun adından hemen sonra virgülle ayrılarak belirtilmelidir.

Fonksiyonun kendisi de ilk parametresinde kendisine iletilen vektöre referans içermelidir. Init çağrısı sırasında vektörün iletilmesine gerek yoktur. Bunu, numpy.arange fonksiyonunu taklit eden Arange fonksiyonunu kullanarak bir örnek üzerinde görelim.

void OnStart()
  {
//---
   vector v;
   v.Init(7,Arange,10,0,0.5); // 3 parameters are passed with Arange call
   Print("v = ", v);
   Print("v.size = ",v.Size());
  }
//+------------------------------------------------------------------+
//|  Values are generated within the half-open interval [start, stop)|
//+------------------------------------------------------------------+
void Arange(vector& v, double stop, double start = 0, double step = 1) // the function has 4 parameters
  {
   if(start >= stop)
     {
      PrintFormat("%s wrong parameters! start=%G  stop=%G", __FILE__,start, stop);
      return;
     }
//---
   int size = (int)((stop - start) / step);
   v.Resize(size);
   double value = start;
   for(ulong i = 0; i < v.Size(); i++)
     {
      v[i] = value;
      value += step;
     }
  }
  
/*
Execution result

v = [0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,8.5,9,9.5]
v.size = 20

*/

Arange fonksiyonunun isteğe bağlı iki parametresi vardır: start ve step. Bu kez de Arange fonksiyonunu Init(7,Arange,10) şeklinde iletelim. Sonuç aşağıdaki gibi olacaktır:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   vector v;
   v.Init(7,Arange,10);
   Print("v = ", v);
   Print("v.size = ",v.Size());
  }
...

/*

v = [0,1,2,3,4,5,6,7,8,9]
v.size = 10

*/


Vektörlerle işlemler

Skaler kullanılarak sıradan toplama, çıkarma, çarpma ve bölme işlemleri vektörler üzerinde gerçekleştirilebilir.

//+------------------------------------------------------------------+
//|                                              vector2_article.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
 {
//---
  vector v= {1, 2, 3, 4, 5};
  Print("Examples without saving vector changes");
  Print("v = ", v);
  Print("v+5 = ", v+5);
  Print("v-Pi= ", v-M_PI);
  Print("v*2.0= ", v*2);
  Print("v/3.0= ", v/3.0);

  Print("Save all vector changes");
  Print("v = ", v);
  Print("v+5 = ", v=v+5);
  Print("v-Pi= ", v=v-M_PI);
  Print("v*2.0= ", v= v*2);
  Print("v/3.0= ", v= v/3.0);
 }
/*
Execution result
   
Examples without saving vector changes
v = [1,2,3,4,5]
v+5 = [6,7,8,9,10]
v-Pi= [-2.141592653589793,-1.141592653589793,-0.1415926535897931,0.8584073464102069,1.858407346410207]
v*2.0= [2,4,6,8,10]
v/3.0= [0.3333333333333333,0.6666666666666666,1,1.333333333333333,1.666666666666667]
Save all vector changes
v = [1,2,3,4,5]
v+5 = [6,7,8,9,10]
v-Pi= [2.858407346410207,3.858407346410207,4.858407346410207,5.858407346410207,6.858407346410207]
v*2.0= [5.716814692820414,7.716814692820414,9.716814692820414,11.71681469282041,13.71681469282041]
v/3.0= [1.905604897606805,2.572271564273471,3.238938230940138,3.905604897606805,4.572271564273471]

*/
//+------------------------------------------------------------------+

Vektörler, aynı büyüklükteki iki vektörün eleman bazında toplanmasını, çıkarılmasını, çarpılmasını ve bölünmesini de destekler.

void OnStart()
  {
//---
   vector a = {1, 2, 3};
   vector b = {2, 4, 6};
   Print("a + b = ", a + b);
   Print("a - b = ", a - b);
   Print("a * b = ", a * b);
   Print("b / a = ", b / a);
  }

/*
Execution result

a + b = [3,6,9]
a - b = [-1,-2,-3]
a * b = [2,8,18]
b / a = [2,2,2]

*/

Dört vektör çarpım işlemi de tanımlanmıştır.

void OnStart()
 {
//---
  vector a={1, 2, 3};
  vector b={4, 5, 6};
  Print("a = ", a);
  Print("b = ", b);
  Print("1) a.Dot(b) = ", a.Dot(b));
  Print("2) a.MatMul(b) = ", a.MatMul(b));
  Print("3) a.Kron(b) = ", a.Kron(b));
  Print("4) a.Outer(b) = \n", a.Outer(b));
 }
/*
Execution result

a = [1,2,3]
b = [4,5,6]
1) a.Dot(b) = 32.0
2) a.MatMul(b) = 32.0
3) a.Kron(b) = [[4,5,6,8,10,12,12,15,18]]
4) a.Outer(b) = 
[[4,5,6]
 [8,10,12]
 [12,15,18]]

*/

Örnekten de görülebileceği gibi, Outer metodu, satır ve sütun sayısının çarpılan vektörlerin büyüklüklerine karşılık geldiği matris geri döndürür. Dot ve MatMul metotları da aynı şekilde çalışır.


Vektörün normu

Vektörün ve matrisin normu, vektörün uzunluğunu (büyüklüğünü, modülünü, mutlak değerini) temsil eder. Bir vektörün normunu hesaplamanın ENUM_VECTOR_NORM numaralandırmasında belirtilen üç yolu vardır.
void OnStart()
 {
//---
  struct str_vector_norm
   {
    ENUM_VECTOR_NORM  norm;
    int               value;
   };
  str_vector_norm vector_norm[]=
   {
     {VECTOR_NORM_INF,       0},
     {VECTOR_NORM_MINUS_INF, 0},
     {VECTOR_NORM_P,         0},
     {VECTOR_NORM_P,         1},
     {VECTOR_NORM_P,         2},
     {VECTOR_NORM_P,         3},
     {VECTOR_NORM_P,         4},
     {VECTOR_NORM_P,         5},
     {VECTOR_NORM_P,         6},
     {VECTOR_NORM_P,         7},
     {VECTOR_NORM_P,        -1},
     {VECTOR_NORM_P,        -2},
     {VECTOR_NORM_P,        -3},
     {VECTOR_NORM_P,        -4},
     {VECTOR_NORM_P,        -5},
     {VECTOR_NORM_P,        -6},
     {VECTOR_NORM_P,        -7}
   };
  vector v{1, 2, 3, 4, 5, 6, 7};
  double norm;
  Print("v = ", v);
//---
  for(int i=0; i<ArraySize(vector_norm); i++)
   {
    switch(vector_norm[i].norm)
     {
      case VECTOR_NORM_INF :
        norm=v.Norm(VECTOR_NORM_INF);
        Print("v.Norm(VECTOR_NORM_INF) = ", norm);
        break;
      case VECTOR_NORM_MINUS_INF :
        norm=v.Norm(VECTOR_NORM_MINUS_INF);
        Print("v.Norm(VECTOR_NORM_MINUS_INF) = ", norm);
        break;
      case VECTOR_NORM_P :
        norm=v.Norm(VECTOR_NORM_P, vector_norm[i].value);
        PrintFormat("v.Norm(VECTOR_NORM_P,%d) = %G", vector_norm[i].value, norm);
     }
   }
 }
/*

v = [1,2,3,4,5,6,7]
v.Norm(VECTOR_NORM_INF) = 7.0
v.Norm(VECTOR_NORM_MINUS_INF) = 1.0
v.Norm(VECTOR_NORM_P,0) = 7
v.Norm(VECTOR_NORM_P,1) = 28
v.Norm(VECTOR_NORM_P,2) = 11.8322
v.Norm(VECTOR_NORM_P,3) = 9.22087
v.Norm(VECTOR_NORM_P,4) = 8.2693
v.Norm(VECTOR_NORM_P,5) = 7.80735
v.Norm(VECTOR_NORM_P,6) = 7.5473
v.Norm(VECTOR_NORM_P,7) = 7.38704
v.Norm(VECTOR_NORM_P,-1) = 0.385675
v.Norm(VECTOR_NORM_P,-2) = 0.813305
v.Norm(VECTOR_NORM_P,-3) = 0.942818
v.Norm(VECTOR_NORM_P,-4) = 0.980594
v.Norm(VECTOR_NORM_P,-5) = 0.992789
v.Norm(VECTOR_NORM_P,-6) = 0.99714
v.Norm(VECTOR_NORM_P,-7) = 0.998813

*/

Normu kullanarak iki vektör arasındaki mesafeyi ölçebiliriz:

void OnStart()
 {
//---
   vector a{1,2,3};
   vector b{2,3,4};
   double distance=(b-a).Norm(VECTOR_NORM_P,2);
   Print("a = ",a);
   Print("b = ",b);
   Print("|a-b| = ",distance);   
 }
/*
Execution result

a = [1,2,3]
b = [2,3,4]
|a-b| = 1.7320508075688772

*/


matrix türü

Vektör, aslında double türünde iki boyutlu bir dizi olan matrisin özel bir halidir. Dolayısıyla, bir matris aynı büyüklükteki vektörlerin bir dizisi olarak ifade edilebilir. Matrisin satır sayısı vektör sayısına, sütun sayısı ise vektörlerin uzunluğuna eşittir. 

Toplama ve çarpma işlemleri matrisler için de mevcuttur. Geleneksel programlama dilleri, matrisleri temsil etmek için dizileri kullanır. Ancak normal diziler birbirleriyle toplanamaz veya çarpılamaz ve normları da yoktur. Matematik birçok farklı matris türünü dikkate alır. Örneğin, birim, simetrik, ters simetrik, üst ve alt üçgensel matrisler ve diğer matrisler.

Vektör metotlarına benzer yerleşik metotlar kullanılarak bir matris oluşturulabilir ve başlatılabilir.

Metot

NumPy analoğu

Açıklama

void static matrix.Eye(const int rows, const int cols, const int ndiag=0)

eye

Belirtilen köşegende 1'lerin ve diğer yerlerde 0'ların olduğu bir matris oluşturur

void matrix.Identity()

identity

Ana köşegende 1'lerin ve diğer yerlerde 0'ların olduğu bir kare matris oluşturur

void static matrix.Ones(const int rows, const int cols)

ones

İstenilen satır ve sütun sayısına sahip 1'lerle dolu bir matris oluşturur

void static matrix.Zeros(const int rows, const int cols)

zeros

İstenilen satır ve sütun sayısına sahip 0'larla dolu bir matris oluşturur

void static matrix.Tri(const int rows, const int cols, const int ndiag=0)
tri  Belirtilen köşegende ve altında 1'lerin ve diğer yerlerde 0'ların olduğu bir matris oluşturur 
void matrix.Diag(const vector v, const int ndiag=0)  diag  Bir köşegeni çıkarır veya bir köşegen matris oluşturur 

void matrix.Full(const int rows, const int cols, const scalar value)

full

İstenilen satır ve sütun sayısına sahip skaler değerle dolu bir matris oluşturur

void matrix.Fill(const scalar value)     Matrisi belirtilen değerle doldurur


Matris oluşturma ve doldurma örnekleri:

void OnStart()
 {
//---
  matrix m{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
  Print("m = \n", m);
  matrix ones=matrix::Ones(4, 4);
  Print("ones = \n", ones);
  matrix zeros=matrix::Zeros(4, 4);
  Print("zeros = \n", zeros);
  matrix eye=matrix::Eye(4, 4);
  Print("eye = \n", eye);

  matrix identity(4, 5);
  Print("matrix_identity\n", identity);
  identity.Identity();
  Print("matrix_identity\n", identity);

  matrix tri=matrix::Tri(3, 4);
  Print("tri = \n", tri);
  Print("tri.Transpose() = \n", tri.Transpose()); // transpose the matrix

  matrix diag(5, 5);
  Print("diag = \n", diag);
  vector d{1, 2, 3, 4, 5};
  diag.Diag(d);
  Print("diag = \n", diag); // insert values from the vector into the matrix diagonal

  matrix fill(5, 5);
  fill.Fill(10);
  Print("fill = \n", fill);

  matrix full =matrix::Full(5, 5, 100);
  Print("full = \n", full);


  matrix init(5, 7);
  Print("init = \n", init);
  m.Init(4, 6);
  Print("init = \n", init);
  
  matrix resize=matrix::Full(2, 2, 5);  
  resize.Resize(5,5);
  Print("resize = \n", resize);  
 }
/*
Execution result

m =
[[1,2,3]
[4,5,6]
[7,8,9]]
ones =
[[1,1,1,1]
[1,1,1,1]
[1,1,1,1]
[1,1,1,1]]
zeros =
[[0,0,0,0]
[0,0,0,0]
[0,0,0,0]
[0,0,0,0]]
eye =
[[1,0,0,0]
[0,1,0,0]
[0,0,1,0]
[0,0,0,1]]
matrix_identity
[[1,0,0,0,0]
[0,1,0,0,0]
[0,0,1,0,0]
[0,0,0,1,0]]
matrix_identity
[[1,0,0,0,0]
[0,1,0,0,0]
[0,0,1,0,0]
[0,0,0,1,0]]
tri =
[[1,0,0,0]
[1,1,0,0]
[1,1,1,0]]
tri.Transpose() =
[[1,1,1]
[0,1,1]
[0,0,1]
[0,0,0]]
diag =
[[0,0,0,0,0]
[0,0,0,0,0]
[0,0,0,0,0]
[0,0,0,0,0]
[0,0,0,0,0]]
diag =
[[1,0,0,0,0]
[0,2,0,0,0]
[0,0,3,0,0]
[0,0,0,4,0]
[0,0,0,0,5]]
fill =
[[10,10,10,10,10]
[10,10,10,10,10]
[10,10,10,10,10]
[10,10,10,10,10]
[10,10,10,10,10]]
full =
[[100,100,100,100,100]
[100,100,100,100,100]
[100,100,100,100,100]
[100,100,100,100,100]
[100,100,100,100,100]]
resize = 
[[5,5,0,0,0]
 [5,5,0,0,0]
 [0,0,0,0,0]
 [0,0,0,0,0]
 [0,0,0,0,0]]

*/

Aşağıdaki örnek, matrisleri doldururken özel fonksiyonların nasıl kullanabileceğini göstermektedir:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
 {
//---
  matrix random(4, 5, MatrixRandom);
  Print("random = \n",random);
  
  matrix init(3, 6, MatrixSetValues);  
  Print("init = \n", init);
  
 }
//+------------------------------------------------------------------+
//| Fills the matrix with random values                              |
//+------------------------------------------------------------------+
void MatrixRandom(matrix& m)
 {
  for(ulong r=0; r<m.Rows(); r++)
   {
    for(ulong c=0; c<m.Cols(); c++)
     {
      m[r][c]=double(MathRand())/32767.;
     }
   }
 }
//+------------------------------------------------------------------+
//| Fills the matrix with powers of a number                         |
//+------------------------------------------------------------------+
void MatrixSetValues(matrix& m, double initial=1)
 {
  double value=initial;
  for(ulong r=0; r<m.Rows(); r++)
   {
    for(ulong c=0; c<m.Cols(); c++)
     {
      m[r][c]=value;
      value*=2;
     }
   }
 } 
 
/*
Execution result

random = 
[[0.4200262459181494,0.5014496292001098,0.7520371105075229,0.652058473464156,0.08783227027191992]
 [0.5991088595233008,0.4311960203863643,0.8718832972197638,0.1350138859218116,0.901882992034669]
 [0.4964445936460463,0.8354747154148991,0.5258339182714317,0.6055482650227363,0.5952940458388012]
 [0.3959166234321116,0.8146916104617451,0.2053590502639851,0.2657551805169835,0.3672292245246742]]
init = 
[[1,2,4,8,16,32]
 [64,128,256,512,1024,2048]
 [4096,8192,16384,32768,65536,131072]]

*/ 

Ayrıca, bir matris, değer başlatma olmadan da iki şekilde oluşturulabilir: 

//--- create a matrix of a given 'rows x cols' size
  matrix m(3, 3);

// ------ equivalent
  matrix m;
  m.Resize(3, 3);


Matrisin normu

Bir matrisin normunu hesaplamanın ENUM_MATRIX_NORM numaralandırmasında belirtilen dokuz yolu vardır.

void OnStart()
  {
//---
   ENUM_MATRIX_NORM matrix_norm[]= {MATRIX_NORM_FROBENIUS,
                                    MATRIX_NORM_SPECTRAL,
                                    MATRIX_NORM_NUCLEAR,
                                    MATRIX_NORM_INF,
                                    MATRIX_NORM_MINUS_INF,
                                    MATRIX_NORM_P1,
                                    MATRIX_NORM_MINUS_P1,
                                    MATRIX_NORM_P2,
                                    MATRIX_NORM_MINUS_P2
                                   };
   matrix m{{1,2,3},{4,5,6},{7,8,9}};
   Print("matrix m:\n",m);
//--- compute the norm using all ways
   double norm;
   for(int i=0; i<ArraySize(matrix_norm); i++)
     {
      norm=m.Norm(matrix_norm[i]);
      PrintFormat("%d. Norm(%s) = %.6f",i+1, EnumToString(matrix_norm[i]),norm);
     }
//---
   return;
  }

/*
Execution result

matrix m:
[[1,2,3]
[4,5,6]
[7,8,9]]
1. Norm(MATRIX_NORM_FROBENIUS) = 16.881943
2. Norm(MATRIX_NORM_SPECTRAL) = 14.790157
3. Norm(MATRIX_NORM_NUCLEAR) = 17.916473
4. Norm(MATRIX_NORM_INF) = 24.000000
5. Norm(MATRIX_NORM_MINUS_INF) = 6.000000
6. Norm(MATRIX_NORM_P1) = 18.000000
7. Norm(MATRIX_NORM_MINUS_P1) = 12.000000
8. Norm(MATRIX_NORM_P2) = 16.848103
9. Norm(MATRIX_NORM_MINUS_P2) = 0.000000

*/


Matrisler ve vektörlerle işlemler

Matrisler, matematik problemlerinin çözülmesi için özel metotlar içerir:

  • Transpozisyon
  • Matrislerin eleman bazında toplanması, çıkarılması, çarpılması ve bölünmesi
  • Matris elemanlarının skalerle toplanması, çıkarılması, çarpılması ve bölünmesi
  • MatMul metoduyla matrislerin ve vektörlerin çarpımı (matris çarpımı)
  • Inner()
  • Outer()
  • Kron()
  • Inv() - matrisin tersini hesaplar
  • Solve() - lineer denklem sistemini çözer
  • LstSq() - lineer cebirsel denklem sisteminin en küçük kareler çözümünü geri döndürür (kare olmayan veya dejenere matrisler için)
  • PInv() - Moore-Penrose yöntemiyle matrisin yalancı tersini hesaplar
  • Sütunlar, satırlar ve köşegenlerle işlemler

Matris ayrışması:

Metot

NumPy analoğu

Açıklama
bool matrix.Cholesky(matrix& L) cholesky Matrisin Cholesky ayrışmasını hesaplar
bool matrix.QR(matrix& Q, matrix& R) qr

Matrisin QR ayrışmasını hesaplar

bool matrix.SVD(matrix& U, matrix& V, vector& singular_values)

svd

Matrisin SVD ayrışmasını hesaplar

bool matrix.Eig(matrix& eigen_vectors, vector& eigen_values)

eig

Kare matrisin özdeğerlerini ve sağ özvektörlerini hesaplar

bool matrix.EigVals(vector& eigen_values)

eigvals

Genel matrisin özdeğerlerini hesaplar

bool matrix.LU(matrix& L, matrix& U)

 

Alt üçgensel matris ve üst üçgensel matrisin çarpımı olan matrisin LU ayrışmasını hesaplar

bool matrix.LUP(matrix& L, matrix& U, matrix& P)

 

Satırların permütasyonuyla LU ayrışması olarak, kısmi pivotlu LUP ayrışması: PA=LU


Matrislerin ve vektörlerin çarpımı

Matrislerin ve vektörlerin matris çarpımını gerçekleştirmek için MatMul() metodu tanımlanmıştır. Bu metot birçok matematik probleminin çözümünde çoğunlukla kullanılır. Bir matris ve bir vektör çarpılırken aşağıdaki iki seçenek mümkündür:

  • Soldaki yatay vektör sağdaki matrisle çarpılır; vektörün uzunluğu matrisin sütun sayısına eşittir
  • Soldaki matris sağdaki dikey vektörle çarpılır; matrisin sütun sayısı vektörün uzunluğuna eşittir

Vektörün uzunluğu, matrisin sütun sayısına eşit değilse, kritik yürütme hatası meydana gelecektir.

İki matrisin çarpılabilmesi için yapılarının şu şekilde olması gerekir: A[M,N] * B[N,K] = C[M,K], yani soldaki matrisin sütun sayısı, sağdaki matrisin satır sayısına eşit olmalıdır. Büyüklükler tutarlı değilse, sonuç boş bir matris olacaktır. Matris çarpımlarının tüm çeşitlerini örneklerle inceleyelim.

void OnStart()
  {
//--- initialize matrices
   matrix m35, m52;
   m35.Init(3,5,Arange);
   m52.Init(5,2,Arange);
//---
   Print("1. Product of horizontal vector v[3] and matrix m[3,5]");
   vector v3 = {1,2,3};
   Print("On the left v3 = ",v3);
   Print("On the right m35 = \n",m35);
   Print("v3.MatMul(m35) = horizontal vector v[5] \n",v3.MatMul(m35));
//--- show that this is really a horizontal vector
   Print("\n2. Product of matrix m[1,3] and matrix m[3,5]");
   matrix m13;
   m13.Init(1,3,Arange,1);
   Print("On the left m13 = \n",m13);
   Print("On the right m35 = \n",m35);
   Print("m13.MatMul(m35) = matrix m[1,5] \n",m13.MatMul(m35));

   Print("\n3. Product of matrix m[3,5] and vertical vector v[5]");
   vector v5 = {1,2,3,4,5};
   Print("On the left m35 = \n",m35);
   Print("On the right v5 = ",v5);
   Print("m35.MatMul(v5) = vertical vector v[3] \n",m35.MatMul(v5));
//--- show that this is really a vertical vector
   Print("\n4. Product of matrix m[3,5] and matrix m[5,1]");
   matrix m51;
   m51.Init(5,1,Arange,1);
   Print("On the left m35 = \n",m35);
   Print("On the right m51 = \n",m51);
   Print("m35.MatMul(m51) = matrix v[3] \n",m35.MatMul(m51));

   Print("\n5. Product of matrix m[3,5] and matrix m[5,2]");
   Print("On the left m35 = \n",m35);
   Print("On the right m52 = \n",m52);
   Print("m35.MatMul(m52) = matrix m[3,2] \n",m35.MatMul(m52));

   Print("\n6. Product of horizontal vector v[5] and matrix m[5,2]");
   Print("On the left v5 = \n",v5);
   Print("On the right m52 = \n",m52);
   Print("v5.MatMul(m52) = horizontal vector v[2] \n",v5.MatMul(m52));

   Print("\n7. Outer() product of horizontal vector v[5] and vertical vector v[3]");
   Print("On the left v5 = \n",v5);
   Print("On the right v3 = \n",v3);
   Print("v5.Outer(v3) = matrix m[5,3] \n",v5.Outer(v3));
//--- show that the product of matrices generates the same result
   Print("\n8. Outer() product of the matrix m[1,5] and matrix m[3,1]");
   matrix m15,m31;
   m15.Init(1,5,Arange,1);
   m31.Init(3,1,Arange,1);
   Print("On the left m[1,5] = \n",m15);
   Print("On the right m31 = \n",m31);
   Print("m15.Outer(m31) = matrix m[5,3] \n",m15.Outer(m31));
  }
//+------------------------------------------------------------------+
//|  Fill the matrix with increasing values                          |
//+------------------------------------------------------------------+
void Arange(matrix & m, double start = 0, double step = 1) // the function has three parameters
  {
//---
   ulong cols = m.Cols();
   ulong rows = m.Rows();
   double value = start;
   for(ulong r = 0; r < rows; r++)
     {
      for(ulong c = 0; c < cols; c++)
        {
         m[r][c] = value;
         value += step;
        }
     }
//---     
  }
/*
Execution result

1. Product of horizontal vector v[3] and matrix m[3,5]
On the left v3 = [1,2,3]
On the right m35 =
[[0,1,2,3,4]
 [5,6,7,8,9]
 [10,11,12,13,14]]
v3.MatMul(m35) = horizontal vector v[5]
[40,46,52,58,64]

2. Product of matrix m[1,3] and matrix m[3,5]
On the left m13 =
[[1,2,3]]
On the right m35 =
[[0,1,2,3,4]
 [5,6,7,8,9]
 [10,11,12,13,14]]
m13.MatMul(m35) = matrix m[1,5]
[[40,46,52,58,64]]

3. Product of matrix m[3,5] and vertical vector v[5]
On the left m35 =
[[0,1,2,3,4]
 [5,6,7,8,9]
 [10,11,12,13,14]]
On the right v5 = [1,2,3,4,5]
m35.MatMul(v5) = vertical vector v[3]
[40,115,190]

4. Product of matrix m[3,5] and matrix m[5,1]
On the left m35 =
[[0,1,2,3,4]
 [5,6,7,8,9]
 [10,11,12,13,14]]
On the right m51 =
[[1]
 [2]
 [3]
 [4]
 [5]]
m35.MatMul(m51) = matrix v[3]
[[40]
 [115]
 [190]]

5. Product of matrix m[3,5] and matrix m[5,2]
On the left m35 =
[[0,1,2,3,4]
 [5,6,7,8,9]
 [10,11,12,13,14]]
On the right m52 =
[[0,1]
 [2,3]
 [4,5]
 [6,7]
 [8,9]]
m35.MatMul(m52) = matrix m[3,2]
[[60,70]
 [160,195]
 [260,320]]

6. The product of horizontal vector v[5] and matrix m[5,2]
On the left v5 =
[1,2,3,4,5]
On the right m52 =
[[0,1]
 [2,3]
 [4,5]
 [6,7]
 [8,9]]
v5.MatMul(m52) = horizontal vector v[2]
[80,95]

7. Outer() product of horizontal vector v[5] and vertical vector v[3]
On the left v5 =
[1,2,3,4,5]
On the right v3 =
[1,2,3]
v5.Outer(v3) = matrix m[5,3]
[[1,2,3]
 [2,4,6]
 [3,6,9]
 [4,8,12]
 [5,10,15]]

8. Outer() product of the matrix m[1,5] and matrix m[3,1]
On the left m[1,5] =
[[1,2,3,4,5]]
On the right m31 =
[[1]
 [2]
 [3]]
m15.Outer(m31) = matrix m[5,3]
[[1,2,3]
 [2,4,6]
 [3,6,9]
 [4,8,12]
 [5,10,15]]

*/

matrix ve vector türlerinin nasıl düzenlendiğini daha iyi anlayabilmek adına, bu örnekler vektörlerin yerine matrislerin nasıl kullanılabileceğini göstermektedir. Bu, vektörlerin matrisler olarak temsil edilebileceği anlamına gelir.


Karmaşık sayılar - complex türü

Bazı matematik problemleri yeni bir veri türü gerektirir: karmaşık sayılar. complex türü bir yapıdır:
struct complex
  {
   double             real;   // real part
   double             imag;   // imaginary part
  };
complex türü, MQL5 fonksiyonları için bir parametre olarak değerle iletilebilir (sadece referansla iletilen sıradan yapıların aksine). DLL'lerden içe aktarılan fonksiyonlar için ise complex türü yalnızca referansla iletilmelidir.

Karmaşık sabitleri tanımlamak için “i” soneki kullanılır:
complex square(complex c)
  {
   return(c*c);
  }
  
void OnStart()
  {
   Print(square(1+2i));  // a constant is passed as a parameter
  }

// will print "(-3,4)" - a string representation of a complex number
Şu anda karmaşık sayılar için yalnızca basit işlemler mevcuttur: =, +, -, *, /, +=, -=, *=, /=, ==, !=.

Ek matematik işlemleri yakında eklenecektir: mutlak değer, sinüs, kosinüs vb. değerlerin hesaplanması.

MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/9805

Veri Bilimi ve Makine Öğrenimi (Bölüm 04): Borsa Çöküşünü Öngörme Veri Bilimi ve Makine Öğrenimi (Bölüm 04): Borsa Çöküşünü Öngörme
Bu makalede, ABD ekonomisinin temel analizine dayalı olarak borsa çöküşünü öngörmek için lojistik modelimizi kullanmaya çalışacağız. Değerlendirmemizi Netflix ve Apple hisse senetleri üzerinde yapacağız ve 2019 ve 2020’deki borsa çöküşlerindeki verileri kullanacağız. Bakalım lojistik modelimiz kasvetli piyasa koşullarında nasıl performans gösterecek.
Volumes göstergesine dayalı bir ticaret sistemi nasıl geliştirilir? Volumes göstergesine dayalı bir ticaret sistemi nasıl geliştirilir?
En popüler teknik göstergelere dayalı ticaret sistemleri geliştirdiğimiz serimizin yeni makalesindeyiz. Bu makalede Volumes göstergesine odaklanacağız. Bir kavram olarak hacim, finansal piyasalarda ticarette çok önemli faktörlerden biridir, dolayısıyla ticaretimizde onu dikkate almalıyız. Bu makale sayesinde, Volumes göstergesiyle basit bir ticaret sisteminin nasıl geliştirileceğini öğreneceğiz.
Veri Bilimi ve Makine Öğrenimi (Bölüm 05): Karar Ağaçları Veri Bilimi ve Makine Öğrenimi (Bölüm 05): Karar Ağaçları
Karar ağaçları, insanların düşünme şeklini taklit ederek verileri sınıflandırır. Bu makalede, karar ağaçlarını nasıl oluşturacağımızı ve onları verileri sınıflandırmak ve öngörmek için nasıl kullanacağımızı göreceğiz. Karar ağacı algoritmasının temel amacı, heterojen verilerden homojen veya homojene yakın verileri ayırmaktır.
MFI göstergesine dayalı bir ticaret sistemi nasıl geliştirilir? MFI göstergesine dayalı bir ticaret sistemi nasıl geliştirilir?
En popüler teknik göstergelere dayalı ticaret sistemleri tasarladığımız makale serimizin bu yeni makalesinde de Money Flow Index (MFI) teknik göstergesini ele alacağız. Onu ayrıntılı olarak inceleyeceğiz ve MetaTrader 5'te kullanılmak üzere MQL5 dili aracılığıyla ona dayalı basit bir ticaret sistemi geliştireceğiz.