| //+------------------------------------------------------------------+
|
| //| matrix.mqh |
|
| //| Copyright 2003-2022 Sergey Bochkanov (ALGLIB project) |
|
| //| Copyright 2012-2023, MetaQuotes Ltd. |
|
| //| https://www.mql5.com |
|
| //+------------------------------------------------------------------+
|
| //| Implementation of ALGLIB library in MetaQuotes Language 5 |
|
| //| |
|
| //| The features of the library include: |
|
| //| - Linear algebra (direct algorithms, EVD, SVD) |
|
| //| - Solving systems of linear and non-linear equations |
|
| //| - Interpolation |
|
| //| - Optimization |
|
| //| - FFT (Fast Fourier Transform) |
|
| //| - Numerical integration |
|
| //| - Linear and nonlinear least-squares fitting |
|
| //| - Ordinary differential equations |
|
| //| - Computation of special functions |
|
| //| - Descriptive statistics and hypothesis testing |
|
| //| - Data analysis - classification, regression |
|
| //| - Implementing linear algebra algorithms, interpolation, etc. |
|
| //| in high-precision arithmetic (using MPFR) |
|
| //| |
|
| //| This file is free software; you can redistribute it and/or |
|
| //| modify it under the terms of the GNU General Public License as |
|
| //| published by the Free Software Foundation (www.fsf.org); either |
|
| //| version 2 of the License, or (at your option) any later version. |
|
| //| |
|
| //| This program is distributed in the hope that it will be useful, |
|
| //| but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| //| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| //| GNU General Public License for more details. |
|
| //+------------------------------------------------------------------+
|
|
|
| #include "arrayresize.mqh"
|
|
|
| class CMatrixDouble;
|
|
|
| //+------------------------------------------------------------------+
|
| //| Rows (double) |
|
| //+------------------------------------------------------------------+
|
| class CRowDouble
|
| {
|
| private:
|
| vector<double> m_array;
|
|
|
| public:
|
| //--- constructors @ destructor
|
| CRowDouble(void) {}
|
| CRowDouble(const vector<double> &vect) { m_array=vect; }
|
| CRowDouble(const double &vect[]) { this=vect; }
|
| CRowDouble(const CRowDouble &vect) { this=vect; }
|
| ~CRowDouble(void) {}
|
|
|
| //--- methods
|
| int Size(void) const { return((int)m_array.Size()); }
|
| bool Resize(const ulong n) { return(m_array.Resize(n)); }
|
| void Set(const int i,const double d) { m_array[i]=d;}
|
| void Add(const int i,const double d) { m_array[i]+=d; }
|
| void Mul(const int i,const double d) { m_array[i]*=d; }
|
| vector<double> Pow(const double p) const { return(MathPow(m_array,p)); }
|
| vector<double> Sqrt(void) { return(MathSqrt(m_array)); }
|
| double Sum(void) { return(m_array.Sum()); }
|
| bool ToArray(double &arr[]);
|
| vector<double> ToVector(void) const { return(m_array); }
|
| vector<double> Abs(void) const { return(MathAbs(m_array)); }
|
| double MaxAbs(void) const { return(MathAbs(m_array)).Max(); }
|
| void Fill(const double value) { m_array.Fill(value); }
|
| void Swap(int i1,int i2);
|
| double Max() { return(m_array.Max()); }
|
| ulong ArgMax() { return(m_array.ArgMax()); }
|
| double Min() { return(m_array.Min()); }
|
| ulong ArgMin() { return(m_array.ArgMin()); }
|
| double Dot(CRowDouble &obj) { return(m_array.Dot(obj.ToVector())); }
|
| double Dot(vector<double> &obj) { return(m_array.Dot(obj)); }
|
| double DotR(CMatrixDouble &obj,int row) { return(m_array.Dot(obj.Row(row))); }
|
| double DotC(CMatrixDouble &obj,int col) { return(m_array.Dot(obj.Col(col))); }
|
| vector<double> MatMul(matrix<double> &obj) { return(m_array.MatMul(obj)); }
|
| vector<double> MatMul(CMatrixDouble &obj) { return(m_array.MatMul(obj.ToMatrix())); }
|
| bool Clip(const double min,const double max) { return(m_array.Clip(min,max)); }
|
| void Copy(const vector<double> &vect,const int n);
|
|
|
| //--- operators
|
| double operator[](const int i) const { return(m_array[i]); }
|
| void operator=(const double &array[]) { m_array.Assign(array); }
|
| void operator=(const vector<double> &vect) { m_array.Assign(vect); }
|
| void operator=(const CRowDouble &vect) { m_array.Assign(vect.m_array); }
|
| vector<double> operator^(const double p) const { return(Pow(p)); }
|
| vector<double> operator/(const double p) const { return(m_array/p); }
|
| vector<double> operator/(const CRowDouble &p) const { return(m_array/p.ToVector()); }
|
| vector<double> operator/(const vector<double> &p) const { return(m_array/p); }
|
| vector<double> operator+(const double value) const { return(m_array+value); }
|
| vector<double> operator+(const vector<double> &vect) const { return(m_array+vect); }
|
| vector<double> operator+(const CRowDouble &vect) const { return(m_array+vect.m_array); }
|
| vector<double> operator+(const double &vect[]) const;
|
| vector<double> operator-(const double value) const { return(m_array-value); }
|
| vector<double> operator-(const vector<double> &vect) const { return(m_array-vect); }
|
| vector<double> operator-(const CRowDouble &vect) const { return(m_array-vect.m_array); }
|
| vector<double> operator-(const double &vect[]) const;
|
| vector<double> operator*(const double value) const { return(m_array*value); }
|
| vector<double> operator*(const CRowDouble &vect) const { return(m_array*vect.m_array); }
|
| void operator/=(const double value) { m_array=m_array/value; }
|
| void operator*=(const double value) { m_array=m_array*value; }
|
| void operator+=(const CRowDouble &vect) { m_array=m_array+vect.m_array; }
|
| void operator+=(const vector<double> &vect) { m_array=m_array+vect; }
|
| void operator+=(const double value) { m_array=m_array+value; }
|
| void operator-=(const double val) { m_array=m_array-val; }
|
| void operator-=(const CRowDouble &vect) { m_array=m_array-vect.m_array; }
|
| void operator-=(const vector<double> &vect) { m_array=m_array-vect; }
|
| void operator-=(const double &vect[]);
|
| void operator*=(const CRowDouble &vect) { m_array=m_array*vect.m_array; }
|
| void operator*=(const vector<double> &vect) { m_array=m_array*vect; }
|
| void operator/=(const CRowDouble &vect) { m_array=m_array/vect.m_array; }
|
| void operator/=(const vector<double> &vect) { m_array=m_array/vect; }
|
| };
|
| //+------------------------------------------------------------------+
|
| //| Method ToArray |
|
| //+------------------------------------------------------------------+
|
| bool CRowDouble::ToArray(double &arr[])
|
| {
|
| ulong size=Size();
|
| if(ArrayResize(arr,(int)size)!=size)
|
| return(false);
|
|
|
| for(ulong i=0; i<size; i++)
|
| arr[i]=m_array[i];
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Method Swap |
|
| //+------------------------------------------------------------------+
|
| void CRowDouble::Swap(int i1,int i2)
|
| {
|
| if(i1>=0 && i2>=0 && i1<(int)Size() && i2<(int)Size())
|
| {
|
| double temp=m_array[i1];
|
| m_array[i1]=m_array[i2];
|
| m_array[i2]=temp;
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Method Copy |
|
| //+------------------------------------------------------------------+
|
| void CRowDouble::Copy(const vector<double> &vect,const int n)
|
| {
|
| if(Size()<=n)
|
| {
|
| m_array=vect;
|
| m_array.Resize(n);
|
| }
|
| else
|
| {
|
| int size=(int)MathMin(n,vect.Size());
|
| for(int i=0; i<size; i++)
|
| m_array[i]=vect[i];
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (+) |
|
| //+------------------------------------------------------------------+
|
| vector<double> CRowDouble::operator+(const double &vect[]) const
|
| {
|
| int size=MathMin(ArraySize(vect),Size());
|
| vector<double> result=m_array;
|
|
|
| for(int i=0; i<size; i++)
|
| result[i]+=vect[i];
|
|
|
| return(result);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (-) |
|
| //+------------------------------------------------------------------+
|
| vector<double> CRowDouble::operator-(const double &vect[]) const
|
| {
|
| int size=MathMin(ArraySize(vect),Size());
|
| vector<double> result=m_array;
|
|
|
| for(int i=0; i<size; i++)
|
| result[i]-=vect[i];
|
|
|
| return(result);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (-=) |
|
| //+------------------------------------------------------------------+
|
| void CRowDouble::operator-=(const double &vect[])
|
| {
|
| int size=MathMin(ArraySize(vect),Size());
|
|
|
| for(int i=0; i<size; i++)
|
| m_array[i]-=vect[i];
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Rows (int) |
|
| //+------------------------------------------------------------------+
|
| class CRowInt
|
| {
|
| private:
|
| int m_array[];
|
|
|
| public:
|
| //--- constructors @ destructor
|
| CRowInt(void) {}
|
| CRowInt(const CRowInt &obj) { this=obj; }
|
| CRowInt(const int &array[]) { this=array; }
|
| ~CRowInt(void) {}
|
| //--- methods
|
| int Size(void) const { return(ArraySize(m_array)); }
|
| void Resize(const int n) { ArrayResizeAL(m_array,n); }
|
| void Set(const int i,const int d) { m_array[i]=d; }
|
| void Add(const int i,const int d) { m_array[i]+=d; }
|
| void Swap(int i1,int i2);
|
| CRowInt Pow(const int p);
|
| long Sum(void);
|
| bool ToArray(int &arr[]);
|
| CRowInt Abs(void) const;
|
| int MaxAbs(void) const;
|
| void Fill(const int value) { ArrayInitialize(m_array,value); }
|
| void Fill(const int value,const int offset,const int count) { ArrayFill(m_array,offset,count,value); }
|
| int Max() { return (Size()>0?m_array[ArrayMaximum(m_array)]:INT_MAX); }
|
| int Min() { return (Size()>0?m_array[ArrayMinimum(m_array)]:INT_MIN); }
|
| long Dot(CRowInt &obj);
|
| void Copy(const CRowInt &obj,const int offset,const int offset_obj,const int count);
|
| void Copy(const int &obj[],const int offset,const int offset_obj,const int count);
|
| void Mul(int pos,int mult) { m_array[pos]=m_array[pos]*mult; }
|
|
|
| //--- operators
|
| int operator[](const int i) const { return(m_array[i]); }
|
| void operator=(const int &array[]);
|
| void operator=(const CRowInt &r);
|
| CRowInt operator^(const int p) { return Pow(p); }
|
| CRowInt operator/(const int p);
|
| CRowInt operator+(const int add);
|
| CRowInt operator+(const CRowInt &add);
|
| CRowInt operator-(const int value);
|
| CRowInt operator-(const CRowInt &value);
|
| CRowInt operator*(const int mult);
|
| void operator/=(const int value);
|
| void operator*=(const int value);
|
| void operator+=(const CRowInt &add) { this=this+add; }
|
| void operator+=(const int add) { this=this+add; }
|
| void operator-=(const CRowInt &value) { this=this-value; }
|
| void operator-=(const int value) { this=this-value; }
|
| };
|
| //+------------------------------------------------------------------+
|
| //| Method Swap |
|
| //+------------------------------------------------------------------+
|
| void CRowInt::Swap(int i1,int i2)
|
| {
|
| if(i1>=0 && i2>=0 && i1<Size() && i2<Size())
|
| {
|
| int temp=m_array[i1];
|
| m_array[i1]=m_array[i2];
|
| m_array[i2]=temp;
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Method Pow |
|
| //+------------------------------------------------------------------+
|
| CRowInt CRowInt::Pow(const int p)
|
| {
|
| int array[];
|
| int size=Size();
|
|
|
| ArrayResize(array,size);
|
| for(int i=0; i<size; i++)
|
| array[i]=(int)MathPow(m_array[i],p);
|
|
|
| return(array);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Method Sum |
|
| //+------------------------------------------------------------------+
|
| long CRowInt::Sum(void)
|
| {
|
| long sum=0;
|
| int size=Size();
|
|
|
| for(int i=0; i<size; i++)
|
| sum+=m_array[i];
|
|
|
| return(sum);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Method ToArray |
|
| //+------------------------------------------------------------------+
|
| bool CRowInt::ToArray(int &arr[])
|
| {
|
| int size=Size();
|
|
|
| if(ArrayResize(arr,size)!=size)
|
| return(false);
|
|
|
| return(ArrayCopy(arr,m_array)==size);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Method Dot |
|
| //+------------------------------------------------------------------+
|
| long CRowInt::Dot(CRowInt &obj)
|
| {
|
| long dot=0;
|
|
|
| if(Size()==obj.Size())
|
| {
|
| int size=Size();
|
| for(int i=0; i<size; i++)
|
| dot+=m_array[i]*obj[i];
|
| }
|
|
|
| return(dot);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Method Copy |
|
| //+------------------------------------------------------------------+
|
| void CRowInt::Copy(const CRowInt &obj,const int offset,const int offset_obj,const int count)
|
| {
|
| ArrayCopy(m_array,obj.m_array,offset,offset_obj,count);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Method Copy |
|
| //+------------------------------------------------------------------+
|
| void CRowInt::Copy(const int &obj[],const int offset,const int offset_obj,const int count)
|
| {
|
| ArrayCopy(m_array,obj,offset,offset_obj,count);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (=) |
|
| //+------------------------------------------------------------------+
|
| void CRowInt::operator=(const int &array[])
|
| {
|
| if(ArraySize(array)>0)
|
| {
|
| ArrayFree(m_array);
|
| ArrayCopy(m_array,array);
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (=) |
|
| //+------------------------------------------------------------------+
|
| void CRowInt::operator=(const CRowInt &r)
|
| {
|
| if(r.Size()>0)
|
| {
|
| ArrayFree(m_array);
|
| ArrayCopy(m_array,r.m_array);
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (+) |
|
| //+------------------------------------------------------------------+
|
| CRowInt CRowInt::operator+(const CRowInt &add)
|
| {
|
| int size1=Size();
|
| int size2=add.Size();
|
| int total=MathMax(size1,size2);
|
| int result[];
|
| //--- check and allocate
|
| if(total>0 && ArrayResize(result,total)==total)
|
| {
|
| //--- filling array
|
| for(int i=0; i<total; i++)
|
| result[i]=(i<size1?m_array[i]:0)+(i<size2?add.m_array[i]:0);
|
| }
|
| //--- return result
|
| return(result);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (+) |
|
| //+------------------------------------------------------------------+
|
| CRowInt CRowInt::operator+(const int add)
|
| {
|
| int total=Size();
|
| int result[];
|
| //--- check and allocate
|
| if(total==0 || ArrayResize(result,total)<total)
|
| return result;
|
| //--- filling array
|
| for(int i=0; i<total; i++)
|
| result[i]=m_array[i]+add;
|
| //--- return result
|
| return(result);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (-) |
|
| //+------------------------------------------------------------------+
|
| CRowInt CRowInt::operator-(const CRowInt &value)
|
| {
|
| int size1=Size();
|
| int size2=value.Size();
|
| int total=MathMax(size1,size2);
|
| int result[];
|
| //--- check and allocate
|
| if(total==0 || ArrayResize(result,total)<total)
|
| return result;
|
| //--- filling array
|
| for(int i=0; i<total; i++)
|
| result[i]=(i<size1?m_array[i]:0)-(i<size2?value.m_array[i]:0);
|
| //--- return result
|
| return(result);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (-) |
|
| //+------------------------------------------------------------------+
|
| CRowInt CRowInt::operator-(const int value)
|
| {
|
| int total=Size();
|
| int result[];
|
| //--- check and allocate
|
| if(total==0 || ArrayResize(result,total)<total)
|
| return result;
|
| //--- filling array
|
| for(int i=0; i<total; i++)
|
| result[i]=m_array[i]-value;
|
| //--- return result
|
| return(result);
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Rows (complex) |
|
| //+------------------------------------------------------------------+
|
| class CRowComplex
|
| {
|
| private:
|
| vector<complex> m_array;
|
| public:
|
| //--- constructor, destructor
|
| CRowComplex(void) {}
|
| CRowComplex(const complex &array[]) { *this=array; }
|
| ~CRowComplex(void) {}
|
|
|
| //--- methods
|
| int Size(void) const { return((int)m_array.Size()); }
|
| void Resize(const ulong n) { m_array.Resize(n); }
|
| void Set(const int i,const complex c) { m_array[i]=c; }
|
| void Set(const int i,const double d) { m_array[i]=d+0i; }
|
| void Mul(const int i,const complex c) { m_array[i]*=c; }
|
| void Mul(const int i,const double d) { m_array[i]*=d+0i; }
|
| void SetRe(const int i,const double d) { m_array[i].real=d; }
|
| void SetIm(const int i,const double d) { m_array[i].imag=d; }
|
| vector<complex> ToVector(void) const { return(m_array); }
|
| bool ToArray(complex &dst[]);
|
|
|
| //--- operators
|
| complex operator[](const int i) const { return(m_array[i]); }
|
| void operator=(const complex &array[]) { m_array.Assign(array); }
|
| void operator=(const CRowComplex &r) { m_array=r.m_array; }
|
| void operator=(const vector<complex> &r) { m_array=r; }
|
| void operator*=(const complex mult);
|
| };
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| bool CRowComplex::ToArray(complex &dst[])
|
| {
|
| int size=Size();
|
| if(ArrayResize(dst,size)!=size)
|
| return(false);
|
|
|
| for(int i=0; i<size; i++)
|
| dst[i]=m_array[i];
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (*=) |
|
| //+------------------------------------------------------------------+
|
| void CRowComplex::operator*=(const complex mult)
|
| {
|
| int size=Size();
|
| for(int i=0; i<size; i++)
|
| m_array[i]*=mult;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Matrix (double) |
|
| //+------------------------------------------------------------------+
|
| class CMatrixDouble
|
| {
|
| private:
|
| matrix<double> m_matrix;
|
|
|
| public:
|
| //--- constructors, destructor
|
| CMatrixDouble(void) {}
|
| CMatrixDouble(const ulong rows) { m_matrix.Resize(rows,1); }
|
| CMatrixDouble(const ulong rows,const ulong cols) { m_matrix.Resize(rows,cols); }
|
| CMatrixDouble(const matrix<double> &mat) { m_matrix=mat; }
|
| CMatrixDouble(const CMatrixDouble& m) { m_matrix=m.m_matrix; }
|
| ~CMatrixDouble(void) {}
|
|
|
| //--- methods
|
| int Size(void) const { return((int)m_matrix.Rows()); }
|
| int Rows(void) const { return((int)m_matrix.Rows()); }
|
| int Cols(void) const { return((int)m_matrix.Cols()); }
|
| vector<double> Row(const int row) const { return(m_matrix.Row(row)); }
|
| bool Row(const int row,const vector<double> &vect) { return(m_matrix.Row(vect,row)); }
|
| bool Row(const int row,const CRowDouble &vect) { return m_matrix.Row(vect.ToVector(),row); }
|
| bool Row(const int row,const CMatrixDouble &mat,const int mat_row) { return(m_matrix.Row(mat.m_matrix.Row(mat_row),row)); }
|
| vector<double> Col(const int col) const { return(m_matrix.Col(col)); }
|
| bool Col(const int col,const vector<double> &vect) { return(m_matrix.Col(vect,col)); }
|
| bool Col(const int col,const CRowDouble &vect) { return(m_matrix.Col(vect.ToVector(),col)); }
|
| bool Col(const int col,const CRowInt &vect);
|
| bool Resize(const ulong n,const ulong m) { return(m_matrix.Resize(n,m)); }
|
| bool Set(const ulong row,const ulong col,double d);
|
| void Add(const ulong row,const ulong col,double d) { m_matrix[row][col]+=d; }
|
| void Mul(const ulong row,const ulong col,double d) { m_matrix[row][col]*=d; }
|
| double Get(const ulong row,const ulong col) const { return(m_matrix[row][col]); }
|
| matrix<double> Abs(void) const { return(MathAbs(m_matrix)); }
|
| matrix<double> Transpose(void) const { return(m_matrix.Transpose()); }
|
| double Max(void) const { return(m_matrix.Max()); }
|
| vector<double> Max(int axis) const { return(m_matrix.Max(axis)); }
|
| double Min(void) const { return(m_matrix.Min()); }
|
| vector<double> Min(int axis) const { return(m_matrix.Min(axis)); }
|
| double Mean(void) const { return(m_matrix.Mean()); }
|
| vector<double> Mean(int axis) const { return(m_matrix.Mean(axis)); }
|
| double Std(void) const { return(m_matrix.Std()); }
|
| vector<double> Std(int axis) const { return(m_matrix.Std(axis)); }
|
| vector<double> Sum(int axis) const { return(m_matrix.Sum(axis)); }
|
| void Split(ulong &parts[],int axis,matrix<double> &splitted[]) const { m_matrix.Split(parts,axis,splitted); }
|
| matrix<double> ToMatrix(void) const { return(m_matrix); }
|
| matrix<double> TriU(const long diag=0) const { return(m_matrix.TriU(diag)); }
|
| matrix<double> TriL(const long diag=0) const { return(m_matrix.TriL(diag)); }
|
| vector<double> Diag(const long diag=0) const { return(m_matrix.Diag(diag)); }
|
| void Diag(const vector<double> &vect,const long diag=0) { m_matrix.Diag(vect,diag); }
|
| void Diag(const CRowDouble &vect,const long diag=0) { m_matrix.Diag(vect.ToVector(),diag); }
|
| bool SwapRows(const ulong row1,const ulong row2) { return(m_matrix.SwapRows(row1,row2)); }
|
| bool SwapCols(const ulong col1,const ulong col2) { return(m_matrix.SwapCols(col1,col2)); }
|
| void Fill(double value) { m_matrix.Fill(value); }
|
| void Fill(double value,int rows,int cols);
|
| matrix<double> MatMul(CMatrixDouble &matr,bool transpose=false);
|
| int Compare(const matrix<double>& mat,const double epsilon=1e-308) { return((int)m_matrix.Compare(mat,epsilon)); }
|
| //---
|
| bool InsertRow(int row);
|
| bool InsertCol(int col);
|
| bool DeleteRow(int row);
|
| bool DeleteCol(int col);
|
|
|
| //--- operators
|
| const vector<double> operator[](const ulong i) const { return(m_matrix.Row(i)); }
|
| void operator=(const matrix<double> &m) { m_matrix.Copy(m); }
|
| void operator=(const CMatrixDouble &m) { m_matrix=m.ToMatrix(); }
|
| matrix<double> operator+(const matrix<double> &m) const;
|
| matrix<double> operator+(const CMatrixDouble &m) const;
|
| matrix<double> operator+(const double value) const { return(m_matrix+value); };
|
| matrix<double> operator-(const matrix<double> &m) const;
|
| matrix<double> operator-(const CMatrixDouble &m) const;
|
| matrix<double> operator-(const double value) const { return(m_matrix-value); };
|
| matrix<double> operator*(const matrix<double> &m) const;
|
| matrix<double> operator*(const CMatrixDouble &m) const;
|
| matrix<double> operator*(const double value) const { return(m_matrix*value); };
|
| matrix<double> operator/(const matrix<double> &m) const;
|
| matrix<double> operator/(const CMatrixDouble &m) const;
|
| matrix<double> operator/(const double value) const { return(m_matrix/value); };
|
| void operator*=(const double value) { m_matrix=m_matrix*value; }
|
| void operator/=(const double value) { m_matrix=m_matrix/value; }
|
| void operator+=(const double value) { m_matrix=m_matrix+value; }
|
| void operator+=(const matrix<double> &value) { m_matrix=m_matrix+value; }
|
| void operator+=(const CMatrixDouble &value) { m_matrix=m_matrix+value.m_matrix; }
|
| void operator-=(const double value) { m_matrix=m_matrix-value; }
|
| void operator-=(const matrix<double> &value) { m_matrix=m_matrix-value; }
|
| void operator-=(const CMatrixDouble &value) { m_matrix=m_matrix-value.m_matrix; }
|
| };
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixDouble::Col(const int col,const CRowInt &vect)
|
| {
|
| if(col>=Cols())
|
| return(false);
|
|
|
| int total=Rows();
|
| int total_data=vect.Size();
|
|
|
| for(int i=0; i<total; i++)
|
| m_matrix[i,col]=(i<total_data?(double)vect[i]:0.0);
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Set value |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixDouble::Set(const ulong row,const ulong col,double d)
|
| {
|
| if(row>=m_matrix.Rows() || col>=m_matrix.Cols())
|
| return(false);
|
|
|
| m_matrix[row][col]=d;
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| void CMatrixDouble::Fill(double value,int rows,int cols)
|
| {
|
| if(rows>(int)Rows())
|
| if(!m_matrix.Resize(rows,MathMin(cols,(int)Cols())))
|
| return;
|
| if(cols>(int)Cols())
|
| if(!m_matrix.Resize(Rows(),cols))
|
| return;
|
|
|
| if(rows==Rows() && cols==Cols())
|
| {
|
| m_matrix.Fill(value);
|
| return;
|
| }
|
|
|
| for(int i=0; i<rows; i++)
|
| for(int j=0; j<cols; j++)
|
| m_matrix[i,j]=value;
|
| }
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| matrix<double> CMatrixDouble::MatMul(CMatrixDouble &matr,bool transpose)
|
| {
|
| if(transpose)
|
| return(m_matrix.MatMul(matr.m_matrix.Transpose()));
|
|
|
| return(m_matrix.MatMul(matr.m_matrix));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixDouble::InsertRow(int row)
|
| {
|
| int rows=(int)Rows();
|
| if(row>rows)
|
| return(false);
|
| if(!m_matrix.Resize(rows+1,Cols()))
|
| return(false);
|
|
|
| for(int i=rows; i>row; i--)
|
| if(!m_matrix.SwapRows(i-1,i))
|
| return(false);
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixDouble::InsertCol(int col)
|
| {
|
| int cols=(int)Cols();
|
| if(col>cols)
|
| return(false);
|
| if(!m_matrix.Resize(Rows(),cols+1))
|
| return(false);
|
|
|
| for(int i=cols; i>col; i--)
|
| if(!m_matrix.SwapCols(i-1,i))
|
| return(false);
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixDouble::DeleteRow(int row)
|
| {
|
| int rows=(int)Rows();
|
| if(row>=rows)
|
| return(false);
|
|
|
| for(int i=row; i<rows-1; i++)
|
| if(!m_matrix.SwapRows(i,i+1))
|
| return(false);
|
|
|
| return(m_matrix.Resize(rows-1,Cols()));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixDouble::DeleteCol(int col)
|
| {
|
| int cols=(int)Cols();
|
| if(col>=cols)
|
| return(false);
|
|
|
| for(int i=col; i<cols-1; i++)
|
| if(!m_matrix.SwapCols(i,i+1))
|
| return(false);
|
|
|
| return(m_matrix.Resize(Rows(),cols-1));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (+) |
|
| //+------------------------------------------------------------------+
|
| matrix<double> CMatrixDouble::operator+(const matrix<double> &m) const
|
| {
|
| if(m_matrix.Rows()!=m.Rows() || m_matrix.Cols()!=m.Cols())
|
| {
|
| matrix<double> zero(0,0);
|
| return(zero);
|
| }
|
|
|
| return(m_matrix+m);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (+) |
|
| //+------------------------------------------------------------------+
|
| matrix<double> CMatrixDouble::operator+(const CMatrixDouble &m) const
|
| {
|
| if(m_matrix.Rows()!=m.Rows() || m_matrix.Cols()!=m.Cols())
|
| {
|
| matrix<double> zero(0,0);
|
| return(zero);
|
| }
|
|
|
| return(m_matrix+m.m_matrix);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (-) |
|
| //+------------------------------------------------------------------+
|
| matrix<double> CMatrixDouble::operator-(const matrix<double> &m) const
|
| {
|
| if(m_matrix.Rows()!=m.Rows() || m_matrix.Cols()!=m.Cols())
|
| {
|
| matrix<double> zero(0,0);
|
| return(zero);
|
| }
|
|
|
| return(m_matrix-m);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (-) |
|
| //+------------------------------------------------------------------+
|
| matrix<double> CMatrixDouble::operator-(const CMatrixDouble &m) const
|
| {
|
| if(m_matrix.Rows()!=m.Rows() || m_matrix.Cols()!=m.Cols())
|
| {
|
| matrix<double> zero(0,0);
|
| return(zero);
|
| }
|
|
|
| return(m_matrix-m.m_matrix);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (*) |
|
| //+------------------------------------------------------------------+
|
| matrix<double> CMatrixDouble::operator*(const matrix<double> &m) const
|
| {
|
| if(m_matrix.Rows()!=m.Rows() || m_matrix.Cols()!=m.Cols())
|
| {
|
| matrix<double> zero(0,0);
|
| return(zero);
|
| }
|
|
|
| return(m_matrix*m);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (*) |
|
| //+------------------------------------------------------------------+
|
| matrix<double> CMatrixDouble::operator*(const CMatrixDouble &m) const
|
| {
|
| if(m_matrix.Rows()!=m.Rows() || m_matrix.Cols()!=m.Cols())
|
| {
|
| matrix<double> zero(0,0);
|
| return(zero);
|
| }
|
|
|
| return(m_matrix*m.m_matrix);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (/) |
|
| //+------------------------------------------------------------------+
|
| matrix<double> CMatrixDouble::operator/(const matrix<double> &m) const
|
| {
|
| if(m_matrix.Rows()!=m.Rows() || m_matrix.Cols()!=m.Cols())
|
| {
|
| matrix<double> zero(0,0);
|
| return(zero);
|
| }
|
|
|
| return(m_matrix/m);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (/) |
|
| //+------------------------------------------------------------------+
|
| matrix<double> CMatrixDouble::operator/(const CMatrixDouble &m) const
|
| {
|
| if(m_matrix.Rows()!=m.Rows() || m_matrix.Cols()!=m.Cols())
|
| {
|
| matrix<double> zero(0,0);
|
| return(zero);
|
| }
|
|
|
| return(m_matrix/m.m_matrix);
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Matrix (int) |
|
| //+------------------------------------------------------------------+
|
| class CMatrixInt
|
| {
|
| private:
|
| CRowInt m_matrix[];
|
|
|
| public:
|
| //--- constructors, destructor
|
| CMatrixInt(void) {}
|
| CMatrixInt(const int rows) { ArrayResizeAL(m_matrix,rows); }
|
| CMatrixInt(const int rows,const int cols);
|
| ~CMatrixInt(void) {}
|
|
|
| //--- methods
|
| int Size(void) const { return(ArraySize(m_matrix)); }
|
| int Rows(void) const { return(Size()); }
|
| int Cols(void) const { return(Size()>0?m_matrix[0].Size():0); }
|
| void Resize(const int n,const int m);
|
| bool Set(const int row,const int col,int d);
|
| int Get(const int row,const int col) const { return(m_matrix[row][col]); }
|
| void Fill(const int value);
|
|
|
| //--- operators
|
| CRowInt *operator[](const int i) const;
|
| void operator=(const CMatrixInt &m);
|
| };
|
| //+------------------------------------------------------------------+
|
| //| Constructor with two parameters |
|
| //+------------------------------------------------------------------+
|
| CMatrixInt::CMatrixInt(const int rows,const int cols)
|
| {
|
| ArrayResizeAL(m_matrix,rows);
|
| for(int i=0; i<rows; i++)
|
| m_matrix[i].Resize(cols);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Resize |
|
| //+------------------------------------------------------------------+
|
| void CMatrixInt::Resize(const int n,const int m)
|
| {
|
| //--- check
|
| if(n<0 || m<0)
|
| return;
|
|
|
| //--- change sizes
|
| ArrayResizeAL(m_matrix,n);
|
| for(int i=0; i<n; i++)
|
| m_matrix[i].Resize(m);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixInt::Set(const int row,const int col,int d)
|
| {
|
| if(row>=ArraySize(m_matrix))
|
| return(false);
|
| if(col>=m_matrix[row].Size())
|
| return(false);
|
|
|
| m_matrix[row].Set(col,d);
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| void CMatrixInt::Fill(const int value)
|
| {
|
| int size=Size();
|
|
|
| for(int i=0; i<size; i++)
|
| m_matrix[i].Fill(value);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Indexing operator |
|
| //+------------------------------------------------------------------+
|
| CRowInt *CMatrixInt::operator[](int i) const
|
| {
|
| return(GetPointer(m_matrix[i]));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Overloading (=) |
|
| //+------------------------------------------------------------------+
|
| void CMatrixInt::operator=(const CMatrixInt &m)
|
| {
|
| int rows=m.Size();
|
| //--- check
|
| if(rows==0)
|
| return;
|
|
|
| int cols=m[0].Size();
|
| //--- check
|
| if(cols==0)
|
| return;
|
|
|
| //--- change size
|
| ArrayResizeAL(m_matrix,rows);
|
| for(int i=0; i<rows; i++)
|
| m_matrix[i].Resize(cols);
|
|
|
| //--- copy
|
| for(int i=0; i<rows; i++)
|
| m_matrix[i]=m[i];
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Matrix (complex) |
|
| //+------------------------------------------------------------------+
|
| class CMatrixComplex
|
| {
|
| private:
|
| matrix<complex> m_matrix;
|
|
|
| public:
|
| //--- constructors, destructor
|
| CMatrixComplex(void) {}
|
| CMatrixComplex(const ulong rows) { m_matrix.Resize(rows,1); }
|
| CMatrixComplex(const ulong rows,const ulong cols) { m_matrix.Resize(rows,cols);}
|
| CMatrixComplex(matrix<complex> &mat) { m_matrix=mat; }
|
| CMatrixComplex(const CMatrixComplex& m) { m_matrix=m.m_matrix; }
|
| ~CMatrixComplex(void) {}
|
|
|
| //--- methods
|
| int Size(void) const { return((int)m_matrix.Rows()); }
|
| int Rows(void) const { return((int)m_matrix.Rows()); }
|
| int Cols(void) const { return((int)m_matrix.Cols()); }
|
| bool Col(const ulong col,vector<complex> &vect) { return m_matrix.Col(vect,col); }
|
| vector<complex> Col(const ulong col) { return m_matrix.Col(col); }
|
| bool Resize(const ulong n,const ulong m) { return(m_matrix.Resize(n,m)); }
|
| bool Set(const ulong row,const ulong col,complex d);
|
| complex Get(const ulong row,const ulong col) const { return m_matrix[row][col]; }
|
| bool Set(const ulong row,const ulong col,const double d);
|
| bool Set(const ulong row,const ulong col,const int d);
|
| bool SetRe(const ulong row,const ulong col,const double d);
|
| bool SetIm(const ulong row,const ulong col,const double d);
|
| bool Mul(const ulong row,const ulong col,const double d);
|
| bool Mul(const ulong row,const ulong col,const int d);
|
| matrix<complex> TriU(const long diag=0) const { return (m_matrix.TriU(diag)); }
|
| matrix<complex> TriL(const long diag=0) const { return (m_matrix.TriL(diag)); }
|
| matrix<complex> ToMatrix(void) const { return (m_matrix); }
|
|
|
| //--- operators
|
| const vector<complex> operator[](const ulong i) const { return(m_matrix.Row(i)); }
|
| void operator=(const CMatrixComplex &m) { m_matrix=m.m_matrix; }
|
| void operator=(const matrix<complex> &m) { m_matrix=m; }
|
| void operator*=(const double value) { m_matrix*=value; }
|
| };
|
| //+------------------------------------------------------------------+
|
| //| Set value |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixComplex::Set(const ulong row,const ulong col,complex d)
|
| {
|
| if(row>=m_matrix.Rows() || col>=m_matrix.Cols())
|
| return(false);
|
|
|
| m_matrix[row][col]=d;
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Set value |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixComplex::Set(const ulong row,const ulong col,double d)
|
| {
|
| if(row>=m_matrix.Rows() || col>=m_matrix.Cols())
|
| return(false);
|
|
|
| m_matrix[row][col]=d+0i;
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Set value |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixComplex::Set(const ulong row,const ulong col,int d)
|
| {
|
| if(row>=m_matrix.Rows() || col>=m_matrix.Cols())
|
| return(false);
|
|
|
| m_matrix[row][col]=(double)d+0i;
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Set value |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixComplex::SetRe(const ulong row,const ulong col,const double d)
|
| {
|
| if(row>=m_matrix.Rows() || col>=m_matrix.Cols())
|
| return(false);
|
|
|
| m_matrix[row][col].real=d;
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Set value |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixComplex::SetIm(const ulong row,const ulong col,const double d)
|
| {
|
| if(row>=m_matrix.Rows() || col>=m_matrix.Cols())
|
| return(false);
|
|
|
| m_matrix[row][col].imag=d;
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Multiplicate value |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixComplex::Mul(const ulong row,const ulong col,double d)
|
| {
|
| if(row>=m_matrix.Rows() || col>=m_matrix.Cols())
|
| return(false);
|
|
|
| m_matrix[row][col]*=d+0i;
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Multiplicate value |
|
| //+------------------------------------------------------------------+
|
| bool CMatrixComplex::Mul(const ulong row,const ulong col,int d)
|
| {
|
| if(row>=m_matrix.Rows() || col>=m_matrix.Cols())
|
| return(false);
|
|
|
| m_matrix[row][col]*=(double)d+0i;
|
|
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|