
MQL5'te matrisler ve vektörler
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) | Belirtilen köşegende 1'lerin ve diğer yerlerde 0'ların olduğu bir matris oluşturur | |
void matrix.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) | İ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) | İ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) | İ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) | Matrisin SVD ayrışmasını hesaplar | |
bool matrix.Eig(matrix& eigen_vectors, vector& eigen_values) | Kare matrisin özdeğerlerini ve sağ özvektörlerini hesaplar | |
bool matrix.EigVals(vector& eigen_values) | 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ü
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





- Ücretsiz ticaret uygulamaları
- 24 saat boyunca ücretsiz Forex VPS
- Ticaret kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Web sitesi politikasını ve kullanım şartlarını kabul edersiniz