//+------------------------------------------------------------------+ //| np.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #include #include #include #define _NP_ #define BEGIN 0 #define STEP 1 #define END LONG_MAX #define BEGIN_REVERSE -1 #define STEP_REVERSE -1 #define END_REVERSE LONG_MIN //+------------------------------------------------------------------+ //| library constants | //+------------------------------------------------------------------+ namespace np { namespace internal { //+------------------------------------------------------------------+ //|find index of a sorted array such that arr[i] <= key < arr[i + 1] | //+------------------------------------------------------------------+ int binary_search(const double key, const double &arr[]) { int imin = 0; int imax = ArraySize(arr)-1; int mid = -1; /* Handle keys outside of the arr range first */ if(key > arr[arr.Size()-1]) { return ArraySize(arr); } else if(key < arr[0]) { return -1; } while(imin<=imax) { mid = (imin+imax)/2; if(midkey) return mid; else { if(key void col(const T &Matrix[], T &Col[], int column, int cols) { int rows = ArraySize(Matrix)/cols; ArrayResize(Col,rows); int start = 0; for(int i=0; i T prodArray(T &in_array[], uint from=0) { T result = T(1); for(uint i = from; i=size)?0:start; return s; } //+------------------------------------------------------------------+ //|process stop parameter | //+------------------------------------------------------------------+ long normalizestop(long stop, ulong size) { long s = (stop>0 && ulong(stop)>=size)?long(size):(stop<0 && ulong(fabs(stop))>size)?-1:(stop<0 && ulong(fabs(stop))<=size)?long(size)+stop:stop; return s; } //+------------------------------------------------------------------+ //| validate all calculated params | //+------------------------------------------------------------------+ bool invalidparams(long start,long stop, long step, ulong size) { if(step==0 || start==stop || ulong(start)>=size || start<0 || ulong(fabs(stop))>size || (step<0 && start0 && start>stop)) return true; return false; } //+------------------------------------------------------------------+ //| quantiles helper function | //+------------------------------------------------------------------+ vector quantile(vector &in,vector &abprobs,vector &probs) { vector x = in; if(!sort(x)) { Print(__FUNCTION__, " sort failure "); vector::Zeros(probs.Size()); } ulong n = x.Size(); if(!x.Size()) { Print(__FUNCTION__, " invalid parameter, empty vector "); vector::Zeros(probs.Size()); } vector aleph = (double(n)*probs+abprobs); vector k = aleph; if(!k.Clip(1.0, double(n-1))) { Print(__FUNCTION__, " error ", GetLastError()); return vector::Zeros(probs.Size()); } k = floor(k); vector gamma = aleph-k; if(!gamma.Clip(0.0, 1.0)) { Print(__FUNCTION__, " error ", GetLastError()); return vector::Zeros(probs.Size()); } vector k1 = k-1.0; ulong index[]; if(!np::vecAsArray(k1,index)) { Print(__FUNCTION__, " error ", GetLastError()); return vector::Zeros(probs.Size()); } vector x1 = np::select(k1,index); ArrayFree(index); if(!np::vecAsArray(k,index)) { Print(__FUNCTION__, " error ", GetLastError()); return vector::Zeros(probs.Size()); } vector x2 = np::select(k,index); return (1.0-gamma)*x1+gamma*x2; } } //+------------------------------------------------------------------+ //| Return arrays representing indices of a grid | //+------------------------------------------------------------------+ void indices(ulong rows, ulong cols, matrix &outRC[]) { ulong N = 2; if(ArrayResize(outRC,2)<0 || !outRC[0].Resize(rows,cols) || !outRC[1].Resize(rows,cols)) { Print(__FUNCTION__, " resize error "); return; } vector v = np::arange(rows); outRC[0] = np::repeat_vector_as_rows_cols(v,cols,false); v = np::arange(cols); outRC[1] = np::repeat_vector_as_rows_cols(v,rows,true); } //+------------------------------------------------------------------+ //| The function sorts (in) vector and indices[] simultaneously | //| using QuickSort algorithm. After sorting the initial ordering | //| of the elements is located in the indices[] array. | //| | //| Arguments: | //| in : vector with values to sort | //| ascending : direction of sort (true:ascending) | //| (false:descending) | //| first : First element index | //| last : Last element index | //| | //| Return value: None | //+------------------------------------------------------------------+ template bool quickSort(vector &in,bool ascending,long first,long last) { long i,j; T p_double,t_double; //--- check if(first<0 || last<0) { return false; } //--- sort i=first; j=last; while(i>1" is quick division by 2 p_double=in[(first+last)>>1]; while(ip_double)) { //--- control the output of the in bounds if(i==in.Size()-1) break; i++; } while((ascending && in[j]>p_double) || (!ascending && in[j] bool quickSortIndices(vector& _in,bool ascending,long &indices[],long first,long last) { vector in = _in; long i,j,t_int; T p_double,t_double; //--- check if(first<0 || last<0) { return false; } //--- sort i=first; j=last; while(i>1" is quick division by 2 p_double=in[(first+last)>>1]; while(ip_double)) { //--- control the output of the in bounds if(i==in.Size()-1) break; i++; } while((ascending && in[j]>p_double) || (!ascending && in[j] bool sort(vector&in, bool ascending=true) { if(in.Size()<1) return false; return quickSort(in,ascending,0,in.Size()-1); } //+------------------------------------------------------------------+ //| sort matrix by columns or rows | //+------------------------------------------------------------------+ template bool sort(matrix&in, bool by_rows, bool ascending=true) { if(by_rows) { for(ulong i = 0; i vector sliceVector(vector &in, const long index_start=BEGIN, const long index_stop = END, const long index_step = STEP) { //---local variables long st,sp,stp,size; //---check function parameters st = internal::normalizestart(index_start,in.Size()); sp = internal::normalizestop(index_stop,in.Size()); stp = index_step; //---error handling if(internal::invalidparams(st,sp,stp,in.Size())) { Print(__FUNCTION__," invalid function parameters "); return vector::Zeros(0); } //---calculate size of new vector size = internal::calculatesize(st,sp,stp); //---initialize output vector vector out(ulong(size)); //---assign elements to output for(long pos = st, index=0; index bool fillVector(vector &in, T value, const long index_start=BEGIN, const long index_stop = END, const long index_step = STEP) { //---local variables long st,sp,stp,size; //---check function parameters st = internal::normalizestart(index_start,in.Size()); sp = internal::normalizestop(index_stop,in.Size()); stp = index_step; //---error handling if(internal::invalidparams(st,sp,stp,in.Size())) { Print(__FUNCTION__," invalid function parameters "); return false; } //---calculate size of new vector size = internal::calculatesize(st,sp,stp); //---assign elements to output for(long pos = st, index=0; index bool reverseVector(vector &in) { if(in.Size()<2) return in.Size()!=0; ulong size = in.Size()-1; ulong half = (in.Size())>>1; for(ulong i = 0; i matrix sliceMatrix(matrix &in, const long row_start=BEGIN, const long row_stop = END, const long row_step = STEP,const long column_start=BEGIN, const long column_stop = END, const long column_step = STEP) { //---local variables long rst,rsp,rstp,rsize,cst,csp,cstp,csize; //---check function parameters for row manipulation rst =internal::normalizestart(row_start,in.Rows()); rsp =internal::normalizestop(row_stop,in.Rows()); rstp = row_step; //---error handling if(internal::invalidparams(rst,rsp,rstp,in.Rows())) { Print(__FUNCTION__," invalid function parameters for row specification "); return matrix::Zeros(0,0); } //---calculate size of new matrix rows rsize = internal::calculatesize(rst,rsp,rstp); //---check function parameters for row manipulation cst = internal::normalizestart(column_start,in.Cols()); csp = internal::normalizestop(column_stop,in.Cols()); cstp = column_step; //---error handling if(internal::invalidparams(cst,csp,cstp,in.Cols())) { Print(__FUNCTION__," invalid function parameters for column specification "); return matrix::Zeros(0,0); } //---calculate size of new matrix columns csize = internal::calculatesize(cst,csp,cstp); //---initialize output matrix matrix out(ulong(rsize),ulong(csize)); //---assign elements to output for(long rpos = rst,row_index = 0; row_index bool fillMatrix(matrix &in, const T value,const long row_start=BEGIN, const long row_stop = END, const long row_step = STEP,const long column_start=BEGIN, const long column_stop = END, const long column_step = STEP) { //---local variables long rst,rsp,rstp,rsize,cst,csp,cstp,csize; //---check function parameters for row manipulation rst =internal::normalizestart(row_start,in.Rows()); rsp =internal::normalizestop(row_stop,in.Rows()); rstp = row_step; //---error handling if(internal::invalidparams(rst,rsp,rstp,in.Rows())) { Print(__FUNCTION__," invalid function parameters for row specification "); return false; } //---calculate size of new matrix rows rsize = internal::calculatesize(rst,rsp,rstp); //---check function parameters for row manipulation cst = internal::normalizestart(column_start,in.Cols()); csp = internal::normalizestop(column_stop,in.Cols()); cstp = column_step; //---error handling if(internal::invalidparams(cst,csp,cstp,in.Cols())) { Print(__FUNCTION__," invalid function parameters for column specification "); return false; } //---calculate size of new matrix columns csize = internal::calculatesize(cst,csp,cstp); //---assign elements to output for(long rpos = rst,row_index = 0; row_index matrix sliceMatrixCols(matrix &in, const long column_start=BEGIN, const long column_stop = END, const long column_step = STEP) { return sliceMatrix(in,BEGIN,END,STEP,column_start,column_stop,column_step); } //+------------------------------------------------------------------+ //|reverse columns of matrix | //+------------------------------------------------------------------+ template bool reverseMatrixCols(matrix &in) { ulong cols = in.Cols()-1; if(in.Cols()<2) return in.Cols()!=0; ulong cols_end = (in.Cols())>>1; for(ulong i = 0; i matrix sliceMatrixRows(matrix &in, const long row_start=BEGIN, const long row_stop = END, const long row_step = STEP) { return sliceMatrix(in,row_start,row_stop,row_step); } //+------------------------------------------------------------------+ //|reverse rows of matrix | //+------------------------------------------------------------------+ template bool reverseMatrixRows(matrix &in) { ulong rows = in.Rows()-1; if(in.Rows()<2) return in.Rows()!=0; ulong rows_end = (in.Rows())>>1; for(ulong i = 0; i bool matrixCopyCols(matrix ©to,matrix ©from, const long dest_start=BEGIN, const long dest_stop = END, const long dest_step = STEP) { return matrixCopy(copyto,copyfrom,BEGIN,END,STEP,dest_start,dest_stop,dest_step); } //+------------------------------------------------------------------+ //| assign values to a portion of matrix selected within range | //| of rows and | //| optional interval | //| with support for negative indexing python style | //| dest_start - row index of first row (inclusive) | //| dest_stop - row index past last row (exclusive) | //| dest_step - row step size | //| indexes refer to positions in copyto | //+------------------------------------------------------------------+ template bool matrixCopyRows(matrix ©to, matrix ©from, const long dest_start=BEGIN, const long dest_stop = END, const long dest_step = STEP) { return matrixCopy(copyto,copyfrom,dest_start,dest_stop,dest_step); } //+------------------------------------------------------------------+ //|return vector of arbitrary elements specified as collection | //| of indices | //+------------------------------------------------------------------+ template vector select(vector &in,const P &indices[]) { P size = (P)MathMin(in.Size(),indices.Size()); if(size<1 || indices[ArrayMaximum(indices,0,int(size))]>=P(in.Size())) { Print(__FUNCTION__, " invalid function parameter "); return vector::Zeros(1); } vector out(size); for(P i=0; i vector select(vector &in,vector &indices) { ulong size = (ulong)MathMin(in.Size(),indices.Size()); if(size<1 || indices.ArgMax()>=in.Size()) { Print(__FUNCTION__, " invalid function parameter "); return vector::Zeros(1); } vector out(size); for(ulong i=0; i vector select(vector &in,const ulong &indices[]) { ulong size = (ulong)MathMin(in.Size(),indices.Size()); if(size<1 || indices[ArrayMaximum(indices,0,int(size))]>=ulong(in.Size())) { Print(__FUNCTION__, " invalid function parameter "); return vector::Zeros(1); } vector out(size); for(ulong i=0; i vector select(vector &in,const int &indices[]) { int size = (int)MathMin(in.Size(),indices.Size()); if(size<1 || indices[ArrayMaximum(indices,0,int(size))]>=int(in.Size())) { Print(__FUNCTION__, " invalid function parameter "); return vector::Zeros(1); } vector out(size); for(int i=0; i vector select(vector &in,const uint &indices[]) { uint size = (uint)MathMin(in.Size(),indices.Size()); if(size<1 || indices[ArrayMaximum(indices,0,int(size))]>=uint(in.Size())) { Print(__FUNCTION__, " invalid function parameter "); return vector::Zeros(1); } vector out(size); for(uint i=0; i matrix selectMatrixCols(matrix &in,const long &indices[]) { ulong size = (ulong)MathMin(in.Cols(),indices.Size()); if(size<1 || indices[ArrayMaximum(indices,0,int(size))]>=long(in.Cols())) { Print(__FUNCTION__," invalid function parameters "); return matrix::Zeros(0,0); } matrix out(in.Rows(),size); for(ulong i=0; i matrix selectMatrixRows(matrix &in,const long &indices[]) { ulong size = (ulong)MathMin(in.Rows(),indices.Size()); if(size<1 || indices[ArrayMaximum(indices,0,int(size))]>=long(in.Rows())) { Print(__FUNCTION__," invalid function parameters "); return matrix::Zeros(0,0); } matrix out(size,in.Cols()); for(ulong i=0; i matrix selectMatrixCols(matrix &in,const ulong &indices[]) { ulong size = (ulong)MathMin(in.Cols(),indices.Size()); if(size<1 || indices[ArrayMaximum(indices,0,int(size))]>=ulong(in.Cols())) { Print(__FUNCTION__," invalid function parameters "); return matrix::Zeros(0,0); } matrix out(in.Rows(),size); for(ulong i=0; i matrix selectMatrixRows(matrix &in,const ulong &indices[]) { ulong size = (ulong)MathMin(in.Rows(),indices.Size()); if(size<1 || indices[ArrayMaximum(indices,0,int(size))]>=ulong(in.Rows())) { Print(__FUNCTION__," invalid function parameters "); return matrix::Zeros(0,0); } matrix out(size,in.Cols()); for(ulong i=0; i matrix selectMatrixCols(matrix &in,vector& indices) { ulong size = (ulong)MathMin(in.Cols(),indices.Size()); if(size<1 || indices.Max()>=double(in.Cols()) || indices.Min()<0.0) { Print(__FUNCTION__," invalid function parameters "); return matrix::Zeros(0,0); } matrix out(in.Rows(),size); for(ulong i=0; i matrix selectMatrixRows(matrix &in,vector& indices) { ulong size = (ulong)MathMin(in.Rows(),indices.Size()); if(size<1 || indices.Max()>=double(in.Rows()) || indices.Min()<0.0) { Print(__FUNCTION__," invalid function parameters "); return matrix::Zeros(0,0); } matrix out(size,in.Cols()); for(ulong i=0; i bool vectorCopy(vector ©to,vector ©from,const long dest_start=BEGIN, const long dest_stop = END, const long dest_step = STEP) { //---local variables long st,sp,stp,size; //---check function parameters st = internal::normalizestart(dest_start,copyto.Size()); sp = internal::normalizestop(dest_stop,copyto.Size()); stp = dest_step; //---error handling if(internal::invalidparams(st,sp,stp,copyto.Size())) { Print(__FUNCTION__," invalid function parameters "); return false; } //---calculate size of new vector size = internal::calculatesize(st,sp,stp); //---error handling if(copyfrom.Size() bool vectorFill(vector ©to, T fill_value,const long dest_start=BEGIN, const long dest_stop = END, const long dest_step = STEP) { //---local variables long st,sp,stp,size; //---check function parameters st = internal::normalizestart(dest_start,copyto.Size()); sp = internal::normalizestop(dest_stop,copyto.Size()); stp = dest_step; //---error handling if(internal::invalidparams(st,sp,stp,copyto.Size())) { Print(__FUNCTION__," invalid function parameters "); return false; } //---calculate size of new vector size = internal::calculatesize(st,sp,stp); //---assign elements for(long pos = st,index=0; index bool matrixCopy(matrix ©to,matrix ©from, const long row_dest_start=BEGIN, const long row_dest_stop = END, const long row_dest_step = STEP,const long column_dest_start=BEGIN, const long column_dest_stop = END, const long column_dest_step = STEP) { //---local variables long rst,rsp,rstp,rsize,cst,csp,cstp,csize; //---check function parameters for row manipulation rst =internal::normalizestart(row_dest_start,copyto.Rows()); rsp =internal::normalizestop(row_dest_stop,copyto.Rows()); rstp = row_dest_step; //---error handling if(internal::invalidparams(rst,rsp,rstp,copyto.Rows())) { Print(__FUNCTION__," invalid function parameters for row specification "); return false; } //---calculate size of new matrix rows rsize = internal::calculatesize(rst,rsp,rstp); //---check function parameters for row manipulation cst = internal::normalizestart(column_dest_start,copyto.Cols()); csp = internal::normalizestop(column_dest_stop,copyto.Cols()); cstp = column_dest_step; //---error handling if(internal::invalidparams(cst,csp,cstp,copyto.Cols())) { Print(__FUNCTION__," invalid function parameters for column specification "); return false; } //---calculate size of new matrix columns csize = internal::calculatesize(cst,csp,cstp); //---error handling if(copyfrom.Cols() < ulong(csize) || copyfrom.Rows() < ulong(rsize)) { Print(__FUNCTION__, " source matrix has insufficient number of columns and/or rows "); return false; } //---assign elements for(long rpos = rst,row_index = 0; row_index bool matrixFill(matrix ©to,T fill_value, const long row_dest_start=BEGIN, const long row_dest_stop = END, const long row_dest_step = STEP,const long column_dest_start=BEGIN, const long column_dest_stop = END, const long column_dest_step = STEP) { //---local variables long rst,rsp,rstp,rsize,cst,csp,cstp,csize; //---check function parameters for row manipulation rst =internal::normalizestart(row_dest_start,copyto.Rows()); rsp =internal::normalizestop(row_dest_stop,copyto.Rows()); rstp = row_dest_step; //---error handling if(internal::invalidparams(rst,rsp,rstp,copyto.Rows())) { Print(__FUNCTION__," invalid function parameters for row specification "); return false; } //---calculate size of new matrix rows rsize = internal::calculatesize(rst,rsp,rstp); //---check function parameters for row manipulation cst = internal::normalizestart(column_dest_start,copyto.Cols()); csp = internal::normalizestop(column_dest_stop,copyto.Cols()); cstp = column_dest_step; //---error handling if(internal::invalidparams(cst,csp,cstp,copyto.Cols())) { Print(__FUNCTION__," invalid function parameters for column specification "); return false; } //---calculate size of new matrix columns csize = internal::calculatesize(cst,csp,cstp); //---assign elements for(long rpos = rst,row_index = 0; row_index vector arange(T start_value, T stop_value, T step_value) { T numerator = (stop_value - start_value); ulong size = ulong((numerator)/step_value); if(MathMod(numerator,step_value)>T(0)) size+=1; vector out = vector::Zeros(size); for(ulong i = 0; i bool arange(T &in_out[],const int size, T value = 0, T step_value = 1) { if(!size) return false; if(ArrayResize(in_out,fabs(size))!=fabs(size)) { Print(__FUNCTION__, " error ", GetLastError()); return false; } for(int i = 0; i vector linspace(T start, T stop, ulong num=50) { vector out(num); if(!num) return vector::Zeros(num); if(num==1) { out[0] = start; return out; } T chunk = (stop-start)/T(num-1); for(ulong i = 0; i bool fillDiagonal(matrix &in_out, T fill_value) { if(in_out.Rows()!=in_out.Cols()) { Print(__FUNCTION__ "Invalid Input. Matrix is not square "); return false; } for(ulong i = 0; i matrix vander(vector &in, ulong num_columns = 0,bool ascending = false) { ulong n = num_columns?num_columns:in.Size(); matrix out(in.Size(),n); for(ulong i = 0; i bool vecAsArray(const vector &in, double &out[]) { //--- if(in.Size()<1) { Print(__FUNCTION__," Empty vector"); return false; } //--- if(ulong(out.Size())!=in.Size() && ArrayResize(out,int(in.Size()))!=int(in.Size())) { Print(__FUNCTION__," resize error ", GetLastError()); return false; } //--- for(uint i = 0; i bool vecAsArray(const vector &in, int &out[]) { //--- if(in.Size()<1) { Print(__FUNCTION__," Empty vector"); return false; } //--- if(ulong(out.Size())!=in.Size() && ArrayResize(out,int(in.Size()))!=int(in.Size())) { Print(__FUNCTION__," resize error ", GetLastError()); return false; } //--- for(uint i = 0; i bool vecAsArray(const vector &in, uint &out[]) { //--- if(in.Size()<1) { Print(__FUNCTION__," Empty vector"); return false; } //--- if(ulong(out.Size())!=in.Size() && ArrayResize(out,int(in.Size()))!=int(in.Size())) { Print(__FUNCTION__," resize error ", GetLastError()); return false; } //--- for(uint i = 0; i bool vecAsArray(const vector &in, long &out[]) { //--- if(in.Size()<1) { Print(__FUNCTION__," Empty vector"); return false; } //--- if(ulong(out.Size())!=in.Size() && ArrayResize(out,int(in.Size()))!=int(in.Size())) { Print(__FUNCTION__," resize error ", GetLastError()); return false; } //--- for(uint i = 0; i bool vecAsArray(const vector &in, ulong &out[]) { //--- if(in.Size()<1) { Print(__FUNCTION__," Empty vector"); return false; } //--- if(ulong(out.Size())!=in.Size() && ArrayResize(out,int(in.Size()))!=int(in.Size())) { Print(__FUNCTION__," resize error ", GetLastError()); return false; } //--- for(uint i = 0; i bool matAsArray(const matrix &in, double &out[]) { //--- if(in.Cols()+in.Rows()<1) { Print(__FUNCTION__," Empty vector"); return false; } //--- if(ulong(out.Size())!=in.Cols()*in.Rows() && ArrayResize(out,int(in.Cols()*in.Rows()))!=int(in.Cols()*in.Rows())) { Print(__FUNCTION__," resize error ", GetLastError()); return false; } //--- for(uint i = 0; i bool matAsArray(const matrix &in, int &out[]) { //--- if(in.Cols()+in.Rows()<1) { Print(__FUNCTION__," Empty vector"); return false; } //--- if(ulong(out.Size())!=in.Cols()*in.Rows() && ArrayResize(out,int(in.Cols()*in.Rows()))!=int(in.Cols()*in.Rows())) { Print(__FUNCTION__," resize error ", GetLastError()); return false; } //--- for(uint i = 0; i bool matAsArray(const matrix &in, uint &out[]) { //--- if(in.Cols()+in.Rows()<1) { Print(__FUNCTION__," Empty vector"); return false; } //--- if(ulong(out.Size())!=in.Cols()*in.Rows() && ArrayResize(out,int(in.Cols()*in.Rows()))!=int(in.Cols()*in.Rows())) { Print(__FUNCTION__," resize error ", GetLastError()); return false; } //--- for(uint i = 0; i bool matAsArray(const matrix &in, long &out[]) { //--- if(in.Cols()+in.Rows()<1) { Print(__FUNCTION__," Empty vector"); return false; } //--- if(ulong(out.Size())!=in.Cols()*in.Rows() && ArrayResize(out,int(in.Cols()*in.Rows()))!=int(in.Cols()*in.Rows())) { Print(__FUNCTION__," resize error ", GetLastError()); return false; } //--- for(uint i = 0; i bool matAsArray(const matrix &in, ulong &out[]) { //--- if(in.Cols()+in.Rows()<1) { Print(__FUNCTION__," Empty vector"); return false; } //--- if(ulong(out.Size())!=in.Cols()*in.Rows() && ArrayResize(out,int(in.Cols()*in.Rows()))!=int(in.Cols()*in.Rows())) { Print(__FUNCTION__," resize error ", GetLastError()); return false; } //--- for(uint i = 0; i vector diff(vector &in, ulong degree = 1) { //--- if(in.Size()<1 || degree<1 || in.Size()::Zeros(0); } //--- vector yy,zz; //--- yy = sliceVector(in,long(degree)); zz = sliceVector(in,BEGIN,long(in.Size()-degree)); //--- return yy-zz; } //+------------------------------------------------------------------+ //| difference matrix about the rows or columns | //+------------------------------------------------------------------+ template matrix diff(matrix &in, ulong degree = 1, bool by_row = true) { //--- if(in.Cols()+in.Rows()<1 || degree<1 || (by_row && in.Cols() yy,zz; //--- if(by_row) { yy = sliceMatrix(in,BEGIN,END,STEP,long(degree)); zz = sliceMatrix(in,BEGIN,END,STEP,BEGIN,long(in.Cols()-degree)); } else { yy = sliceMatrix(in,long(degree)); zz = sliceMatrix(in,BEGIN,long(in.Rows()-degree)); } //--- return yy-zz; } //+------------------------------------------------------------------+ //| generate vector of num_repetitions of input vector elements | //+------------------------------------------------------------------+ template vector repeat_vector_elements(vector &vect,ulong num_repetitions) { vector out(num_repetitions*vect.Size()); for(ulong i = 0; i vector repeat_matrix_elements(matrix &in, ulong num_repetitions) { vector out(num_repetitions*in.Cols()*in.Rows()); for(ulong i = 0; i matrix repeat_vector_as_rows_cols(vector&in, ulong num_repetitions, bool as_rows = true) { matrix out(as_rows?num_repetitions:in.Size(),as_rows?in.Size():num_repetitions); for(ulong i = 0; i matrix repeat_matrix_rows_cols(matrix &in, ulong num_repetitions, bool by_rows) { if(num_repetitions<1) { Print(__FUNCTION__, " invalid function parameter "); return matrix::Zeros(0,0); } matrix out((by_rows)?num_repetitions*in.Rows():in.Rows(),(!by_rows)?num_repetitions*in.Cols():in.Cols()); if(by_rows) for(ulong i = 0; i matrix repeat_matrix_rows_cols(matrix &in, ulong &reps[],bool by_rows) { ulong max = 0 ; for(uint i = 0; i::Zeros(0,0); } matrix out((by_rows)?max:in.Rows(),(!by_rows)?max:in.Cols()); if(by_rows) for(ulong i = 0, j = 0; i matrix vectorAsColumnMatrix(vector&in, ulong num_cols) { return repeat_vector_as_rows_cols(in,num_cols,false); } //+------------------------------------------------------------------+ //| generate matrix by repeating vector as rows | //+------------------------------------------------------------------+ template matrix vectorAsRowMatrix(vector&in, ulong num_rows) { return repeat_vector_as_rows_cols(in,num_rows,true); } //+------------------------------------------------------------------+ //| The function extracts the unique values from the vector. | //| | //| Arguments: | //| in : vector with values | //| | //| | //| Return value: out vector of unique values . | //+------------------------------------------------------------------+ template vector unique(vector &in) { //--- check array size ulong size=in.Size(); if(size==0) { Print(__FUNCTION__," Invalid function parameter "); return vector::Zeros(1); } //--- prepare additional in bool checked[]; if(ArrayResize(checked,int(size))!=int(size)) { Print(__FUNCTION__," error ",GetLastError()); return vector::Zeros(0) ; } ArrayFill(checked,0,int(size),false); //--- prepare out in vectorout(size); //--- find unique elements ulong unique_count=0; T value=0; while(true) { bool flag=false; for(ulong i=unique_count; i bool unique(vector &in, vector &out, long &indices[],long &counts[]) { //--- check vector size ulong size=in.Size(); if(size==0) { Print(__FUNCTION__," Invalid function parameter "); return false; } //--- prepare internal and output buffers bool checked[]; if(ArrayResize(checked,int(size))!=int(size) || ArrayResize(indices,int(size))!=int(size) || ArrayResize(counts,int(size))!=int(size) || !out.Resize(size)) { Print(__FUNCTION__, " error ", GetLastError()); return(false); } ArrayFill(checked,0,int(size),false); ArrayFill(indices,0,int(size),-1); ArrayFill(counts,0,int(size),1); //--- prepare out vector out.Resize(size); //--- find unique elements ulong unique_count=0; T value=0; while(true) { bool flag=false; for(ulong i=unique_count; i matrix unique(matrix &in,int axis = 0) { vector sum = in.Sum(axis); vector spec; long indices[],counts[]; if(!unique(sum,spec,indices,counts)) { Print(__FUNCTION__,": error "); return matrix::Zeros(0,0); } if(axis) return selectMatrixRows(in,indices); else return selectMatrixCols(in,indices); } //+------------------------------------------------------------------+ //|Integrate using the composite trapezoidal rule | //+------------------------------------------------------------------+ template T trapezoid(vector&y, vector&x,T dx=1) { vectord; if(x.Size()==0) { d = vector::Zeros(y.Size()); d.Fill(dx); } else d = diff(x); vector ret = (d*(sliceVector(y,1) + sliceVector(y,0,-1)))/2.0; return ret.Sum(); } //+---------------------------------------------------------------------------------+ //| One-dimensional linear interpolation for monotonically increasing sample points.| //+---------------------------------------------------------------------------------+ template vectorinterp(vector &xv,vector& xpoints,vector &ypoints,double left=DBL_MIN,double right=DBL_MAX, double period=EMPTY_VALUE) { vectorout = vector::Zeros(xv.Size()); if(period != EMPTY_VALUE) { if(period == 0.0) { Print(__FUNCTION__," period should be non zero"); return out; } vector x = xv; vector xp = xpoints; vector yp = ypoints; vector vp(x.Size()); vp.Fill(MathAbs(period)); x = MathMod(xv,vp); xp = MathMod(xpoints,vp); long indices[]; if(!arange(indices,int(xp.Size())) || !quickSortIndices(xp,true,indices,0,long(xp.Size()-1))) { Print(__FUNCTION__, " ", __LINE__); return out; } xp = select(xp,indices); yp = select(yp,indices); if(!xpoints.Resize((xp.Size()*2)+1) || !ypoints.Resize((yp.Size()*2)+1)) { Print(__FUNCTION__, " ", __LINE__, " error ", GetLastError()); return out; } if(!vectorCopy(xpoints,xp,xp.Size(),xp.Size()*2) || !vectorCopy(ypoints,yp,yp.Size(),yp.Size()*2)) { Print(__FUNCTION__, " ", __LINE__); return out; } xpoints[xpoints.Size()-1] = xp[0]+MathAbs(period); ypoints[ypoints.Size()-1] = yp[0]; if(!reverseVector(xp)) { Print(__FUNCTION__, " ", __LINE__); return out; } vector temp = xp-vp; if(!vectorCopy(xpoints,temp,0,temp.Size())) { Print(__FUNCTION__, " ", __LINE__); return out; } if(!reverseVector(yp) && !vectorCopy(ypoints,yp,0,yp.Size())) { Print(__FUNCTION__, " ", __LINE__); return out; } xv = x; } double lval,rval; double xvals[]; if(!vecAsArray(xpoints,xvals) || !ArraySort(xvals)) { Print(__FUNCTION__, " ", __LINE__," error ", GetLastError()); return out; } lval=(left==DBL_MIN)?ypoints[0]:left; rval=(right==DBL_MAX)?ypoints[ypoints.Size()-1]:right; if(xpoints.Size()==1) { for(ulong i =0; ixpoints[0])?rval:ypoints[0]; } else { vector slopes=vector::Zeros(0); if(xpoints.Size()<=xv.Size()) slopes = vector::Zeros(xpoints.Size()-1); if(slopes.Size()) { vector ypd = sliceVector(ypoints,1) - sliceVector(ypoints,0,ypoints.Size()-1); vector xpd = sliceVector(xpoints,1) - sliceVector(xpoints,0,xpoints.Size()-1); slopes = ypd/xpd; } int j = 0; for(ulong i = 0; i matrix matmul(const matrix& matrix_a, const matrix& matrix_b) { matrix matrix_c = matrix::Zeros(0,0); if(matrix_a.Cols()!=matrix_b.Rows()) return(matrix_c); ulong M=matrix_a.Rows(); ulong K=matrix_a.Cols(); ulong N=matrix_b.Cols(); matrix_c=matrix::Zeros(M,N); for(ulong m=0; m vector matmul(const matrix& matrix_a, const vector& vector_b) { matrix matrix_b = matrix::Zeros(vector_b.Size(),1); matrix_b.Col(vector_b,0); matrixout = matmul(matrix_a,matrix_b); return out.Col(0); } //+------------------------------------------------------------------+ //| Find indices where elements should be inserted to maintain order | //+------------------------------------------------------------------+ template bool searchsorted(vector&sorted,vector&sample,bool right_side, vector &out) { out = vector::Zeros(sample.Size()); vector samplesorted = sample; if(!np::sort(samplesorted,sorted[0]<=sorted[sorted.Size()-1])) { Print(__FUNCTION__, " error ", GetLastError()); return false; } for(ulong j = 0; jsorted.Max()) || (right_side && sample[j]>=sorted.Max())) { out[j] = double(sorted.Size()); break; } } } } } return true; } //+------------------------------------------------------------------+ //|matrix and vector addition with broadcasting | //+------------------------------------------------------------------+ template matrix add(matrix&mat, vector&vec) { if(vec.Size()!=mat.Cols() && vec.Size()!=mat.Rows()) { Print(__FUNCTION__, " operands could not be broadcast together ", " (",mat.Rows(),":",mat.Cols(), ") and (", vec.Size(),")"); return matrix::Zeros(0,0); } matrixout=matrix::Zeros(mat.Rows(),mat.Cols()); if(vec.Size() == mat.Cols()) for(ulong i = 0; i matrix minus(matrix&mat, vector&vec) { if(vec.Size()!=mat.Cols() && vec.Size()!=mat.Rows()) { Print(__FUNCTION__, " operands could not be broadcast together ", " (",mat.Rows(),":",mat.Cols(), ") and (", vec.Size(),")"); return matrix::Zeros(0,0); } matrixout=matrix::Zeros(mat.Rows(),mat.Cols()); if(vec.Size() == mat.Cols()) for(ulong i = 0; i matrix minus(vector&vec, matrix&mat) { if(vec.Size()!=mat.Cols() && vec.Size()!=mat.Rows()) { Print(__FUNCTION__, " operands could not be broadcast together ", " (",mat.Rows(),":",mat.Cols(), ") and (", vec.Size(),")"); return matrix::Zeros(0,0); } matrixout=matrix::Zeros(mat.Rows(),mat.Cols()); if(vec.Size()==mat.Cols()) for(ulong i = 0; i vector minus(vector& va, vector& vb) { if(va.Size()==vb.Size()) return va-vb; else { if(va.Size()!=1 && vb.Size()!=1) { Print(__FUNCTION__, " operands could not be broadcast together "); return vector::Zeros(0); } else { if(vb.Size()>va.Size()) return va[0] - vb; else return va - vb[0]; } } } //+------------------------------------------------------------------+ //| vector addition with broadcasting | //+------------------------------------------------------------------+ template vector add(vector& va, vector& vb) { if(va.Size()==vb.Size()) return va+vb; else { if(va.Size()!=1 && vb.Size()!=1) { Print(__FUNCTION__, " operands could not be broadcast together "); return vector::Zeros(0); } else { if(vb.Size()>va.Size()) return va[0] + vb; else return va + vb[0]; } } } //+------------------------------------------------------------------+ //| vector multiplication with broadcasting | //+------------------------------------------------------------------+ template vector multiply(vector& va, vector& vb) { if(va.Size()==vb.Size()) return va*vb; else { if(va.Size()!=1 && vb.Size()!=1) { Print(__FUNCTION__, " operands could not be broadcast together "); return vector::Zeros(0); } else { if(vb.Size()>va.Size()) return va[0]*vb; else return va*vb[0]; } } } //+------------------------------------------------------------------+ //| vector division with broadcasting | //+------------------------------------------------------------------+ template vector divide(vector& va, vector& vb) { if(va.Size()==vb.Size()) return va/vb; else { if(va.Size()!=1 && vb.Size()!=1) { Print(__FUNCTION__, " operands could not be broadcast together "); return vector::Zeros(0); } else { if(vb.Size()>va.Size()) return va[0]/vb; else return va/vb[0]; } } } //+------------------------------------------------------------------+ //|matrix and vector mulitiplication with broadcasting | //+------------------------------------------------------------------+ template matrix multiply(matrix&mat, vector&vec) { if(vec.Size()!=mat.Cols() && vec.Size()!=mat.Rows()) { Print(__FUNCTION__, " operands could not be broadcast together ", " (",mat.Rows(),":",mat.Cols(), ") and (", vec.Size(),")"); return matrix::Zeros(0,0); } matrixout=matrix::Zeros(mat.Rows(),mat.Cols()); if(vec.Size() == mat.Cols()) for(ulong i = 0; i matrix divide(matrix&mat, vector&vec) { if(vec.Size()!=mat.Cols() && vec.Size()!=mat.Rows()) { Print(__FUNCTION__, " operands could not be broadcast together ", " (",mat.Rows(),":",mat.Cols(), ") and (", vec.Size(),")"); return matrix::Zeros(0,0); } matrixout=matrix::Zeros(mat.Rows(),mat.Cols()); if(vec.Size() == mat.Cols()) for(ulong i = 0; i matrix divide(vector&vec, matrix&mat) { if(vec.Size()!=mat.Cols() && vec.Size()!=mat.Rows()) { Print(__FUNCTION__, " operands could not be broadcast together ", " (",mat.Rows(),":",mat.Cols(), ") and (", vec.Size(),")"); return matrix::Zeros(0,0); } matrixout=matrix::Zeros(mat.Rows(),mat.Cols()); if(vec.Size() == mat.Cols()) for(ulong i = 0; i vectorravelMultiIndex(vector &in[], ulong&dims[]) { vector vdims; if(!vdims.Assign(dims)) { Print(__FUNCTION__, " error ", GetLastError()); return vector::Zeros(1); } vector vec = np::sliceVector(vdims,1); if(!np::reverseVector(vec)) { Print(__FUNCTION__, " error ", GetLastError()); return vector::Zeros(1); } vec = vec.CumProd(); if(!np::reverseVector(vec)) { Print(__FUNCTION__, " error ", GetLastError()); return vector::Zeros(1); } vector nvec = vector::Ones(vec.Size()+1); if(!vectorCopy(nvec,vec,1)) { Print(__FUNCTION__, " error ", GetLastError()); return vector::Zeros(1); } matrixout(in.Size(),in[0].Size()); for(ulong i = 0; i vector binEdges(vector&in, ulong numbins=3) { T first_edge = in.Min(); T last_edge = in.Max(); return np::linspace(first_edge,last_edge,numbins); } /*+------------------------------------------------------------------+ //| numpy digitize for scalar values | //+------------------------------------------------------------------+ template long digitize(T sample, vector&edges, bool right_side=false) { for(long i = 1; iedges.Max()) || (!right_side && sample>=edges.Max())) return long(edges.Size()); } } } return -1; } //+------------------------------------------------------------------+ //| Compute the multidimensional histogram of some data. | //+------------------------------------------------------------------+ template bool histogramdd(matrix&in, ulong bins, vector &hist, vector &edges[]) { hist = vector::Zeros(ulong(pow(bins,in.Cols()))); if(edges.Size()) ArrayFree(edges); if(!bins) bins=3; if(ArrayResize(edges,int(in.Cols()))<0) { Print(__FUNCTION__, " error ", GetLastError()); return false; } for(ulong i = 0; irow = in.Row(i); long final_index=0; for(ulong j =0; j=long(hist.Size()) || final_index<0) { Print(__FUNCTION__, " hist index out of bounds. Index ", final_index, " hist size ", hist.Size()); return false; } hist[final_index] +=1.0; } return true; } //+------------------------------------------------------------------+ //| Compute the multidimensional histogram of some data. | //+------------------------------------------------------------------+ template bool histogramdd(matrix&in, ulong &bins[], vector &hist, vector &edges[]) { hist = vector::Zeros(np::internal::prodArray(bins)); if(edges.Size()) ArrayFree(edges); if(ulong(bins.Size())row = in.Row(i); long final_index=0; for(ulong j =0; j=long(hist.Size()) || final_index<0) { Print(__FUNCTION__, " hist index out of bounds. Index ", final_index, " hist size ", hist.Size()); return false; } hist[final_index] +=1.0; } return true; } //+------------------------------------------------------------------+ //| Compute the one dimensional histogram of some data. | //+------------------------------------------------------------------+ template bool histogram(vector&in, ulong bins, vector &hist, vector &edges) { hist = vector::Zeros(in.Size()); if(!bins) bins=3; if(in.Size()/2 < bins) { Print(__FUNCTION__, " invalid parameters, too few observations relative to the number of bins "); return false; } edges = np::linspace(in.Min(), in.Max(),bins+1); for(ulong j =0; j vectorbitwiseNot(vector&left) { int aleft[]; int res[]; if(left.Size()<1) { Print(__FUNCTION__, " invalid function input "); return vector::Zeros(left.Size()); } if(!vecAsArray(left,aleft)) { Print(__FUNCTION__, " vector conversion failed "); return vector::Zeros(left.Size()); } if(!MathBitwiseNot(aleft,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return vector::Zeros(left.Size()); } vector vec; if(!vec.Assign(res)) { Print(__FUNCTION__ " Array assignment to vector failed ", GetLastError()); return vector::Zeros(left.Size()); } return vec; } //+------------------------------------------------------------------+ //|BitwiseAnd | //+------------------------------------------------------------------+ template vectorbitwiseAnd(vector&left,vector&right) { int aleft[]; int aright[]; int res[]; if(left.Size()!=right.Size() || right.Size()<1) { Print(__FUNCTION__, " invalid function inputs "); return vector::Zeros(left.Size()); } if(!vecAsArray(left,aleft) || !vecAsArray(right,aright)) { Print(__FUNCTION__, " vector conversion failed "); return vector::Zeros(left.Size()); } if(!MathBitwiseAnd(aleft,aright,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return vector::Zeros(left.Size()); } vector vec; if(!vec.Assign(res)) { Print(__FUNCTION__ " Array assignment to vector failed ", GetLastError()); return vector::Zeros(left.Size()); } return vec; } //+------------------------------------------------------------------+ //|BitwiseOr | //+------------------------------------------------------------------+ template vectorbitwiseOr(vector&left,vector&right) { int aleft[]; int aright[]; int res[]; if(left.Size()!=right.Size() || right.Size()<1) { Print(__FUNCTION__, " invalid function inputs "); return vector::Zeros(left.Size()); } if(!vecAsArray(left,aleft) || !vecAsArray(right,aright)) { Print(__FUNCTION__, " vector conversion failed "); return vector::Zeros(left.Size()) } if(!MathBitwiseOr(aleft,aright,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return vector::Zeros(left.Size()); } vector vec; if(!vec.Assign(res)) { Print(__FUNCTION__ " Array assignment to vector failed ", GetLastError()); return vector::Zeros(left.Size()); } return vec; } //+------------------------------------------------------------------+ //|BitwiseXor | //+------------------------------------------------------------------+ template vectorbitwiseXor(vector&left,vector&right) { int aleft[]; int aright[]; int res[]; if(left.Size()!=right.Size() || right.Size()<1) { Print(__FUNCTION__, " invalid function inputs "); return vector::Zeros(left.Size()); } if(!vecAsArray(left,aleft) || !vecAsArray(right,aright)) { Print(__FUNCTION__, " vector conversion failed "); return vector::Zeros(left.Size()) } if(!MathBitwiseXor(aleft,aright,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return vector::Zeros(left.Size()); } vector vec; if(!vec.Assign(res)) { Print(__FUNCTION__ " Array assignment to vector failed ", GetLastError()); return vector::Zeros(left.Size()); } return vec; } //+------------------------------------------------------------------+ //|BitwiseShiftL | //+------------------------------------------------------------------+ template vectorbitwiseShiftL(vector&left,int shift) { int aleft[]; int res[]; if(!left.Size() || shift<1) { Print(__FUNCTION__, " invalid function inputs "); return vector::Zeros(left.Size()); } if(!vecAsArray(left,aleft)) { Print(__FUNCTION__, " vector conversion failed "); return vector::Zeros(left.Size()) } if(!MathBitwiseShiftL(aleft,shift,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return vector::Zeros(left.Size()); } vector vec; if(!vec.Assign(res)) { Print(__FUNCTION__ " Array assignment to vector failed ", GetLastError()); return vector::Zeros(left.Size()); } return vec; } //+------------------------------------------------------------------+ //|BitwiseShiftR | //+------------------------------------------------------------------+ template vectorbitwiseShiftR(vector&left,int shift) { int aleft[]; int res[]; if(!left.Size() || shift<1) { Print(__FUNCTION__, " invalid function inputs "); return vector::Zeros(left.Size()); } if(!vecAsArray(left,aleft)) { Print(__FUNCTION__, " vector conversion failed "); return vector::Zeros(left.Size()) } if(!MathBitwiseShiftR(aleft,shift,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return vector::Zeros(left.Size()); } vector vec; if(!vec.Assign(res)) { Print(__FUNCTION__ " Array assignment to vector failed ", GetLastError()); return vector::Zeros(left.Size()); } return vec; } //+------------------------------------------------------------------+ //|BitwiseNot | //+------------------------------------------------------------------+ template matrixbitwiseNot(matrix&left) { int aleft[]; int res[]; if(!left.Rows() || !left.Cols()) { Print(__FUNCTION__, " invalid function input "); return matrix::Zeros(left.Rows(),left.Cols()); } if(!matAsArray(left,aleft)) { Print(__FUNCTION__, " matrix conversion failed "); return matrix::Zeros(left.Rows(),left.Cols()) } if(!MathBitwiseNot(aleft,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } matrix mat; if(!mat.Assign(res) || !mat.Reshape(left.Rows(),left.Cols())) { Print(__FUNCTION__ " Array assignment to matrix failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } return mat; } //+------------------------------------------------------------------+ //|BitwiseAnd | //+------------------------------------------------------------------+ template matrixbitwiseAnd(matrix&left,matrix&right) { int aleft[]; int aright[]; int res[]; if(!left.Rows() || !left.Cols() || !right.Cols() || !right.Rows()) { Print(__FUNCTION__, " invalid function inputs "); return matrix::Zeros(left.Rows(),left.Cols()); } if(!matAsArray(left,aleft) || !matAsArray(right,aright)) { Print(__FUNCTION__, " matrix conversion failed "); return matrix::Zeros(left.Rows(),left.Cols()) } if(!MathBitwiseAnd(aleft,aright,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } matrix mat; if(!mat.Assign(res) || !mat.Reshape(left.Rows(),left.Cols())) { Print(__FUNCTION__ " Array assignment to matrix failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } return mat; } //+------------------------------------------------------------------+ //|BitwiseOr | //+------------------------------------------------------------------+ template matrixbitwiseOr(matrix&left,matrix&right) { int aleft[]; int aright[]; int res[]; if(!left.Rows() || !left.Cols() || !right.Cols() || !right.Rows()) { Print(__FUNCTION__, " invalid function inputs "); return matrix::Zeros(left.Rows(),left.Cols()); } if(!matAsArray(left,aleft) || !matAsArray(right,aright)) { Print(__FUNCTION__, " matrix conversion failed "); return matrix::Zeros(left.Rows(),left.Cols()) } if(!MathBitwiseOr(aleft,aright,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } matrix mat; if(!mat.Assign(res) || !mat.Reshape(left.Rows(),left.Cols())) { Print(__FUNCTION__ " Array assignment to matrix failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } return mat; } //+------------------------------------------------------------------+ //|BitwiseXor | //+------------------------------------------------------------------+ template matrixbitwiseXor(matrix&left,matrix&right) { int aleft[]; int aright[]; int res[]; if(!left.Rows() || !left.Cols() || !right.Cols() || !right.Rows()) { Print(__FUNCTION__, " invalid function inputs "); return matrix::Zeros(left.Rows(),left.Cols()); } if(!matAsArray(left,aleft) || !matAsArray(right,aright)) { Print(__FUNCTION__, " matrix conversion failed "); return matrix::Zeros(left.Rows(),left.Cols()) } if(!MathBitwiseXor(aleft,aright,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } matrix mat; if(!mat.Assign(res) || !mat.Reshape(left.Rows(),left.Cols())) { Print(__FUNCTION__ " Array assignment to matrix failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } return mat; } //+------------------------------------------------------------------+ //|BitwiseShiftL | //+------------------------------------------------------------------+ template matrixbitwiseShiftL(matrix&left,int shift) { int aleft[]; int res[]; if(!left.Rows() || !left.Cols() || shift<1) { Print(__FUNCTION__, " invalid function inputs "); return matrix::Zeros(left.Rows(),left.Cols()); } if(!matAsArray(left,aleft)) { Print(__FUNCTION__, " matrix conversion failed "); return matrix::Zeros(left.Rows(),left.Cols()) } if(!MathBitwiseShiftL(aleft,shift,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } matrix mat; if(!mat.Assign(res) || !mat.Reshape(left.Rows(),left.Cols())) { Print(__FUNCTION__ " Array assignment to matrix failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } return mat; } //+------------------------------------------------------------------+ //|BitwiseShiftR | //+------------------------------------------------------------------+ template matrixbitwiseShiftR(matrix&left,int shift) { int aleft[]; int res[]; if(!left.Rows() || !left.Cols() || shift<1) { Print(__FUNCTION__, " invalid function inputs "); return matrix::Zeros(left.Rows(),left.Cols()); } if(!matAsArray(left,aleft)) { Print(__FUNCTION__, " matrix conversion failed "); return matrix::Zeros(left.Rows(),left.Cols()) } if(!MathBitwiseShiftR(aleft,shift,res)) { Print(__FUNCTION__ " MathBitwiseNot failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } matrix mat; if(!mat.Assign(res) || !mat.Reshape(left.Rows(),left.Cols())) { Print(__FUNCTION__ " Array assignment to matrix failed ", GetLastError()); return matrix::Zeros(left.Rows(),left.Cols()); } return mat; } //+------------------------------------------------------------------+ //| write matrix to csv file | //+------------------------------------------------------------------+ template bool matrix2csv(string csv_name, matrix &matrix_, string header_string="", bool common=false, int digits=8) { FileDelete(csv_name); int handle = FileOpen(csv_name,FILE_WRITE|FILE_CSV|FILE_ANSI|(common?FILE_COMMON:FILE_ANSI),",",CP_UTF8); if(header_string == "") for(ulong i=0; i row = {}; datetime time_start = GetTickCount(), current_time; string header[]; ushort u_sep; u_sep = StringGetCharacter(",",0); StringSplit(header_string,u_sep, header); vector colsinrows = matrix_.Row(0); if(ArraySize(header) != (int)colsinrows.Size()) { printf("headers=%d and columns=%d from the matrix vary is size ",ArraySize(header),colsinrows.Size()); return false; } //--- string header_str = ""; for(int i=0; i0) //Avoid the first column which contains the column's header { ++all_size; ArrayResize(Arr,all_size); Arr[all_size-1] = data; } //--- if(FileIsLineEnding(handle)) { cols_total=column; ++rows; column = 0; } } FileClose(handle); } int rows =all_size/cols_total; Comment(""); matrix mat(rows, cols_total); string Col[]; vector col_vector; for(int i=0; i bool sampleVector(vector &in,const ulong count,vector &result) { if(!in.Size()) return false; //--- prepare target array and calculate values if(result.Size() vector choice(vector& a, vector& p, ulong size = 0, bool replace = true) { ulong pop_size = a.Size(); vector idx; if(!pop_size && size) { Print(__FUNCTION__, " a cannot be empty unless no samples are taken "); return vector::Zeros(0); } if(p.Size()) { ulong d = p.Size(); double atol = DBL_EPSILON; if(d!=pop_size) { Print(__FUNCTION__, " a and p must have same size "); return vector::Zeros(0); } double psum = p.Sum(); if(p.Min()<0.0) { Print(__FUNCTION__, " probabilities cannot be negative "); return vector::Zeros(0); } if(psum-1.>atol) { Print(__FUNCTION__, " probabilities must sum to 1 "); return vector::Zeros(0); } } CHighQualityRandStateShell rstate; CHighQualityRand::HQRndRandomize(rstate.GetInnerObj()); bool is_scalar = (size==0); ulong shape = 0; vector cdf; if(!is_scalar) shape = size; else size = 1; if(replace) { if(p.Size()) { cdf = p.CumSum(); cdf/=cdf[cdf.Size()-1]; vector uniform_samples = vector::Zeros(shape); for(ulong i = 0; i::Zeros(0); } } else { idx = vector::Zeros(size); for(ulong i = 0; ipop_size) { Print(__FUNCTION__, " cannot take a larger sample thatn population when replace = false "); return vector::Zeros(0); } if(p.Size()) { ulong n_uniq = 0; vector pp = p; vector found = vector::Zeros(shape); vector cdf,_new,temp; long uindices[],counted[]; while(n_uniq0) { for(ulong i = 0; i bool sampleVector(vector &in,const ulong count,const bool replace,vector &result) { //--- Sampling with Replacement if(replace) return sampleVector(in,count,result); if(!in.Size()) return(false); //--- prepare target array if(result.Size() bool sampleArray(T &array[],const ulong count,T &result[]) { if(!array.Size()) return false; //--- prepare target array and calculate values if(result.Size() bool sampleArray(T &array[],const ulong count,const bool replace,T &result[]) { //--- Sampling with Replacement if(replace) return sampleArray(array,count,result); if(!array.Size()) return(false); //--- prepare target array if(result.Size() bool epdf(const vector &vec,const ulong count,vector &x,vector &pdf) { if(count<=1) return(false); ulong size=vec.Size(); if(size==0) return(false); //--- check NaN values for(ulong i=0; i bool ecdf(const vector &vec,const ulong count,vector &x,vector &cdf) { if(count<1) return(false); ulong size=vec.Size(); if(size==0) return(false); //--- check NaN values if(vec.HasNan()) { Print(__FUNCTION__," input data contains invalid number(s)"); return false; } //--- prepare output arrays if(x.Size() pdf; if(!pdf.Resize(count)) return(false); for(ulong i=0; i double spearmanRho(vector &vec1,vector &vec2) { ulong size=vec1.Size(); if(size<1 || vec2.Size()!=size) { Print(__FUNCTION__, " vector lengths donot match "); return(EMPTY_VALUE); } //--- calculate ranks vector rank_x = rankVector(vec1); vector rank_y = rankVector(vec2); //--- return rank_x.CorrCoef(rank_y); } //+------------------------------------------------------------------+ //| MathCorrelationKendall | //+------------------------------------------------------------------+ template double kendalTau(const vector &vec1,const vector &vec2) { double tau = double("nan"); ulong size=vec1.Size(); if(size==0 || vec2.Size()!=size) { Print(__FUNCTION__, " size of input vectors donot match "); return(tau); } //--- long cnt1=0,cnt2=0,cnt=0; //--- for(long i=0; i0.0) ++cnt; else cnt--; } } } //--- calculate Kendall tau long den=cnt1*cnt2; if(den==0) { Print(__FUNCTION__, " failed zero check at line 3139 "); return tau; } tau=double(cnt)/MathSqrt(den); //--- return(tau); } //+------------------------------------------------------------------+ //| MathRank | //+-------------------------------------------------------------------+ template vector rankVector(vector &in_vec) { vector rank = vector::Ones(in_vec.Size()); ulong size=in_vec.Size(); if(size<1) return rank; if(size==1) { rank[0]=1; return rank; } //--- prepare arrays vectorvalues = in_vec; ulong indices[]; //--- if(!arange(indices,int(size))) return rank; //--- ulong i,j,k,t,tmpi; double tmp; //--- sort if(size!=1) { i=2; do { t=i; while(t!=1) { k=t/2; if(values[k-1]>=values[t-1]) t=1; else { //--- swap tmp=values[k-1]; values[k-1]=values[t-1]; values[t-1]=tmp; tmpi=indices[k-1]; indices[k-1]=indices[t-1]; indices[t-1]=tmpi; t=k; } } i=i+1; } while(i<=size); i=size-1; do { //--- swap tmp=values[i]; values[i]=values[0]; values[0]=tmp; tmpi=indices[i]; indices[i]=indices[0]; indices[0]=tmpi; t=1; while(t!=0) { k=2*t; if(k>i) t=0; else { if(kvalues[k-1]) ++k; if(values[t-1]>=values[k-1]) t=0; else { //--- swap tmp=values[k-1]; values[k-1]=values[t-1]; values[t-1]=tmp; tmpi=indices[k-1]; indices[k-1]=indices[t-1]; indices[t-1]=tmpi; t=k; } } } i=i-1; } while(i>=1); } //--- compute tied ranks i=0; while(i vector whereVectorIsLt(vector&in, const T value) { vectorout = vector::Zeros(in.Size()); for(ulong i = 0; i vector whereVectorIsLte(vector&in, const T value) { vectorout = vector::Zeros(in.Size()); for(ulong i = 0; i condition | //+------------------------------------------------------------------+ template vector whereVectorIsGt(vector&in, const T value) { vectorout = vector::Zeros(in.Size()); for(ulong i = 0; ivalue) out[i] = 1.0; } return out; } //+------------------------------------------------------------------+ //| masking vector based on >= condition | //+------------------------------------------------------------------+ template vector whereVectorIsGte(vector&in, const T value) { vectorout = vector::Zeros(in.Size()); for(ulong i = 0; i=value) out[i] = 1.0; } return out; } //+------------------------------------------------------------------+ //| masking matrix based on < condition | //+------------------------------------------------------------------+ template matrix whereMatrixIsLt(matrix&in, const T value) { matrixout = matrix::Zeros(in.Rows(),in.Cols()); for(ulong i = 0; i matrix whereMatrixIsLte(matrix&in, const T value) { matrixout = matrix::Zeros(in.Rows(),in.Cols()); for(ulong i = 0; i condition | //+------------------------------------------------------------------+ template matrix whereMatrixIsGt(matrix&in, const T value) { matrixout = matrix::Zeros(in.Rows(),in.Cols()); for(ulong i = 0; ivalue) out[i][j] = 1.0; } return out; } //+------------------------------------------------------------------+ //| masking matrix based on >= condition | //+------------------------------------------------------------------+ template matrix whereMatrixIsGte(matrix&in, const T value) { matrixout = matrix::Zeros(in.Rows(),in.Cols()); for(ulong i = 0; i=value) out[i][j] = 1.0; } return out; } //+------------------------------------------------------------------+ //| masking vector based on == condition by digits | //+------------------------------------------------------------------+ template vector whereVectorIsEq(vector&in, const T value, int _digits = 8) { vectorout = vector::Zeros(in.Size()); for(ulong i = 0; i matrix whereMatrixIsEq(matrix&in, const T value, int _digits = 8) { matrixout = matrix::Zeros(in.Rows(),in.Cols()); for(ulong i = 0; i=value) out[i][j] = 1.0; } return out; } //+------------------------------------------------------------------+ //| replace vector members that are not numbers | //+------------------------------------------------------------------+ template vector replace_whereVectorIsNaN(vector&in,const T fill = 0.0) { vectorout = in; if(in.HasNan()==in.Size()) { out.Fill(fill); return out; } for(ulong i = 0; i matrix replace_whereMatrixIsNaN(matrix&in,const T fill = 0.0) { matrixout = in; if(in.HasNan()==(in.Rows()*in.Cols())) { out.Fill(fill); return out; } for(ulong i = 0; i bool copyToSelectCols(matrix ©to, matrix &from, vector &v_mask) { if(from.Cols()!=copyto.Cols() || v_mask.Size()!=copyto.Cols()) { Print(__FUNCTION__, " invalid parameters "); return false; } for(ulong i = 0; i bool copyToSelectRows(matrix ©to, matrix from, vector &v_mask) { if(from.Rows()!=copyto.Rows() || v_mask.Size()!=copyto.Rows()) { Print(__FUNCTION__, " invalid parameters "); return false; } for(ulong i = 0; i bool copySelectElements(vector ©to, vector &from, vector &v_mask) { if(from.Size()!=copyto.Size() || v_mask.Size()!=copyto.Size()) { Print(__FUNCTION__, " invalid parameters "); return false; } for(ulong i = 0; i T sign(const T a) { if(aT(0)) return T(1); else return T(0); } //+------------------------------------------------------------------+ //| calculation of raw moment about specified center | //+------------------------------------------------------------------+ double moment(vector& a, ulong order, double mean=NULL) { if(!a.Size()) return a.Mean(); if(order == 0 || (order == 1 && !mean)) return order==0?1.0:0.; ulong list[]; ArrayResize(list,list.Size()+1,100); list[list.Size()-1]=order; ulong current = order; while(current>2) { if(MathMod(current,2)) current=(current-1)/2; else current/=2; ArrayResize(list,list.Size()+1,100); list[list.Size()-1]= current; } double mn = (mean == 0.0)?a.Mean():mean; vector azeromean = a - mn; vector s; if(list[list.Size()-1] == 1) s = azeromean; else s = pow(azeromean,2.); for(int i = int(list.Size())-2; i>=0; --i) { s = pow(s,2.0); if(MathMod(i,2)) s*=azeromean; } return s.Mean(); } //+------------------------------------------------------------------+ //| sin(pi*x) | //+------------------------------------------------------------------+ template T sinpi(T x) { T s = 1.0; if(x < 0.0) { x = -x; s = -1.0; } T r = fmod(x, 2.0); if(r < 0.5) { return s * sin(M_PI * r); } else if(r > 1.5) { return s * sin(M_PI * (r - 2.0)); } else { return -s * sin(M_PI * (r - 1.0)); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double lgam_large_x(double x) { const double LS2PI = 0.91893853320467274178; double q = (x - 0.5) * log(x) - x + LS2PI; if(x > 1.0e8) { return (q); } double p = 1.0 / (x * x); p = ((7.9365079365079365079365e-4 * p - 2.7777777777777777777778e-3) * p + 0.0833333333333333333333) / x; return q + p; } //+------------------------------------------------------------------+ //| helper | //+------------------------------------------------------------------+ double polevl(double x, double &coef[], int N) { double ans; int i; int p; p = 0; ans = coef[p++]; i = N; do { ans = ans * x + coef[p++]; } while(--i != 0); return (ans); } //+------------------------------------------------------------------+ //| helper | //+------------------------------------------------------------------+ double p1evl(double x, double &coef[], int N) { double ans; uint p; int i; p = 0; ans = x + coef[p++]; i = N - 1; do ans = ans * x + coef[p++]; while(--i != 0); return (ans); } //+------------------------------------------------------------------+ //| sign of log gamma | //+------------------------------------------------------------------+ double lgam_sgn(double x, int &sign) { double p, q, u, w, z; int i; const double LS2PI = 0.91893853320467274178; const double MAXLGM = 2.556348e305; double gamma_A[] = { 8.11614167470508450300E-4, -5.95061904284301438324E-4, 7.93650340457716943945E-4, -2.77777777730099687205E-3, 8.33333333333331927722E-2 }; double gamma_B[] = { -1.37825152569120859100E3, -3.88016315134637840924E4, -3.31612992738871184744E5, -1.16237097492762307383E6, -1.72173700820839662146E6, -8.53555664245765465627E5 }; double gamma_C[] = { -3.51815701436523470549E2, -1.70642106651881159223E4, -2.20528590553854454839E5, -1.13933444367982507207E6, -2.53252307177582951285E6, -2.01889141433532773231E6 }; sign = 1; if(MathClassify(x)!=FP_NORMAL) { return x; } if(x < -34.0) { q = -x; w = lgam_sgn(q, sign); p = floor(q); if(p == q) { Print(__FUNCTION__, " singular error "); return (double("inf")); } i = (int)p; if((i & 1) == 0) { sign = -1; } else { sign = 1; } z = q - p; if(z > 0.5) { p += 1.0; z = p - q; } z = q * sinpi(z); if(z == 0.0) { Print(__FUNCTION__, " singular error "); return (double("inf")); } z = log(M_PI) - log(z) - w; return (z); } if(x < 13.0) { z = 1.0; p = 0.0; u = x; while(u >= 3.0) { p -= 1.0; u = x + p; z *= u; } while(u < 2.0) { if(u == 0.0) { Print(__FUNCTION__, " singular error "); return (double("inf")); } z /= u; p += 1.0; u = x + p; } if(z < 0.0) { sign = -1; z = -z; } else { sign = 1; } if(u == 2.0) { return (log(z)); } p -= 2.0; x = x + p; p = x * polevl(x, gamma_B, 5) / p1evl(x, gamma_C, 6); return (log(z) + p); } if(x>MAXLGM) return sign*double("inf"); if(x>=1000.) return lgam_large_x(x); q = (x-0.5)*log(x) - x +LS2PI; p = 1./(x*x); return q+polevl(p,gamma_A,4)/x; } //+-------------------------------------------------------------------------+ //| Asymptotic expansion for ln(|B(a, b)|) for a > ASYMP_FACTOR*max(|b|, 1)| //+-------------------------------------------------------------------------+ double lbeta_asymp(double a, double b, int &sgn) { double r = lgam_sgn(b, sgn); r -= b * log(a); r += b * (1 - b) / (2 * a); r += b * (1 - b) * (1 - 2 * b) / (12 * a * a); r += -b * b * (1 - b) * (1 - b) / (12 * a * a * a); return r; } //+------------------------------------------------------------------+ //| Special case for a negative integer argument | //+------------------------------------------------------------------+ double beta_negint(int a, double b) { int sgn; if(b == int(b) && 1 - a - b > 0) { sgn = (MathMod(b, 2) == 0) ? 1 : -1; return sgn * CBetaF::Beta(1. - a - b, b); } else { Print(__FUNCTION__, " overflow error "); return double("inf"); } } //+------------------------------------------------------------------+ //| helper | //+------------------------------------------------------------------+ double lbeta_negint(int a, double b) { double r; if(b == int(b) && 1 - a - b > 0) { r = lbeta(1 - a - b, b); return r; } else { Print(__FUNCTION__, " overflow error "); return double("inf"); } } //+------------------------------------------------------------------+ //| helper | //+------------------------------------------------------------------+ double lbeta(double a, double b) { double y; int sign; const double MAXGAM = 171.624376956302725; const double beta_ASYMP_FACTOR = 1e6; sign = 1; if(a <= 0.0) { if(a == floor(a)) { if(a == int(a)) { return lbeta_negint(int(a), b); } else { Print(__FUNCTION__, " overflow error "); return (sign * double("inf")); } } } if(b <= 0.0) { if(b == floor(b)) { if(b == int(b)) { return lbeta_negint(int(b), a); } else { Print(__FUNCTION__, " overflow error "); return (sign * double("inf")); } } } if(MathAbs(a) < MathAbs(b)) { y = a; a = b; b = y; } if(MathAbs(a) > beta_ASYMP_FACTOR * MathAbs(b) && a > beta_ASYMP_FACTOR) { /* Avoid loss of precision in lgam(a + b) - lgam(a) */ y = lbeta_asymp(a, b, sign); return y; } y = a + b; if(MathAbs(y) > MAXGAM || MathAbs(a) > MAXGAM || MathAbs(b) > MAXGAM) { int sgngam; y = lgam_sgn(y, sgngam); sign *= sgngam; /* keep track of the sign */ y = lgam_sgn(b, sgngam) - y; sign *= sgngam; y = lgam_sgn(a, sgngam) + y; sign *= sgngam; return (y); } y = CGammaFunc::GammaFunc(y); a = CGammaFunc::GammaFunc(a); b = CGammaFunc::GammaFunc(b); if(y == 0.0) { Print(__FUNCTION__, " overflow error "); return (sign * double("inf")); } if(MathAbs(MathAbs(a) - MathAbs(y)) > MathAbs(MathAbs(b) - MathAbs(y))) { y = b / y; y *= a; } else { y = a / y; y *= b; } if(y < 0) { y = -y; } return (log(y)); } //+------------------------------------------------------------------+ //| Binomial coefficient | //+------------------------------------------------------------------+ double binom(double n, double k) { double kx,nx,num, den, dk, sgn; if(n < 0) { nx = floor(n); if(n == nx) { // Undefined return double("nan"); } } kx = floor(k); if(k == kx && (MathAbs(n) > 1e-8 || n == 0)) { nx = floor(n); if(nx == n && kx > nx / 2 && nx > 0) { // Reduce kx by symmetry kx = nx - kx; } if(kx >= 0 && kx < 20) { num = 1.0; den = 1.0; for(int i = 1; i < 1 + int(kx); i++) { num *= i + n - kx; den *= i; if(MathAbs(num) > 1e50) { num /= den; den = 1.0; } } return num / den; } } // general case if(n >= 1e10 * k && k > 0) { // avoid under/overflows intermediate results return exp(-lbeta(1 + n - k, 1 + k) - log(n + 1)); } if(k > 1e8 * MathAbs(n)) { // avoid loss of precision num = CGammaFunc::GammaFunc(1 + n) / MathAbs(k) + CGammaFunc::GammaFunc(1 + n) * n / (2 * k * k); // + ... num /= M_PI * pow(MathAbs(k), n); if(k > 0) { kx = floor(k); if(int(kx) == kx) { dk = k - kx; sgn = (MathMod(int(kx), 2) == 0) ? 1 : -1; } else { dk = k; sgn = 1; } return num * sin((dk - n) * M_PI) * sgn; } kx = floor(k); if(int(kx) == kx) { return 0; } return num * sin(k * M_PI); } return 1 / (n + 1) / CBetaF::Beta(1 + n - k, 1 + k); } //+------------------------------------------------------------------+ //| N choose K | //+------------------------------------------------------------------+ template T comb(ulong N, T k, bool exact=false, bool repetition = false) { if(repetition) return comb(N+ulong(k)-1,(T)k,exact); if(exact) return comb(N,k); else { bool cond = false; cond = ((k<=T(N)) && (N>=0) && (k>=0)); T val = (T)binom(double(N),double(k)); if(!cond) val = 0; return val; } } //+------------------------------------------------------------------+ //| Compute the kurtosis (Fisher or Pearson) of a dataset. | //+------------------------------------------------------------------+ double kurtosis(vector& in,bool fisher=true, bool bias=true) { ulong n = in.Size(); double out; double mean = in.Mean(); double m2 = moment(in,2,mean); double m4 = moment(in,4,mean); bool zero = (m2<= pow(mean*2.e-16,2.)); out = (!zero)?m4/pow(m2,2.):double("nan"); if(!bias) { bool cancorrect = (~zero&(n>3)); double nval = 1.0/(n-2)/(n-3) * ((pow(n,2)-1.0)*m4/pow(m2,2.0) - 3*pow((n-1),2.0)); if(cancorrect) out = nval + 3.; else out = double("nan"); } if(fisher) out = out - 3.; return out; } //+------------------------------------------------------------------+ //| get element wise maximum | //+------------------------------------------------------------------+ vector maximum(vector &x, vector &y) { if(x.Size()!=y.Size()) { Print(__FUNCTION__, " vector size mismatch "); return vector::Zeros(0); } matrix xy(x.Size(),2); if(!xy.Col(x,0) || !xy.Col(y,1)) { Print(__FUNCTION__, " column insertion error ", GetLastError()); return vector::Zeros(0); } return xy.Max(1); } //+------------------------------------------------------------------+ //| get element wise minimum | //+------------------------------------------------------------------+ vector minimum(vector &x, vector &y) { if(x.Size()!=y.Size()) { Print(__FUNCTION__, " vector size mismatch "); return vector::Zeros(0); } matrix xy(x.Size(),2); if(!xy.Col(x,0) || !xy.Col(y,1)) { Print(__FUNCTION__, " column insertion error ", GetLastError()); return vector::Zeros(0); } return xy.Min(1); } //+------------------------------------------------------------------+ //| get element wise maximum | //+------------------------------------------------------------------+ vector maximum(vector &x, double v) { vector y(x.Size()); y.Fill(v); matrix xy(x.Size(),2); if(!xy.Col(x,0) || !xy.Col(y,1)) { Print(__FUNCTION__, " column insertion error ", GetLastError()); return vector::Zeros(0); } return xy.Max(1); } //+------------------------------------------------------------------+ //| get element wise minimum | //+------------------------------------------------------------------+ vector minimum(vector &x, double v) { vector y(x.Size()); y.Fill(v); matrix xy(x.Size(),2); if(!xy.Col(x,0) || !xy.Col(y,1)) { Print(__FUNCTION__, " column insertion error ", GetLastError()); return vector::Zeros(0); } return xy.Min(1); } //+------------------------------------------------------------------+ //| return vector with elements that meet certain condition | //+------------------------------------------------------------------+ template vector whereIsNan(vector& in) { ulong any = in.HasNan(); if(any) { vector out = vector::Zeros(any) ulong count = 0; for(ulong i = 0; i vector whereIsNotNan(vector& in) { ulong any = in.HasNan(); if(any) { vector out = vector::Zeros(in.Size() - any); ulong count = 0; for(ulong i = 0; i matrix toeplitz(vector& x) { ulong n = x.Size(); matrix out(n,n); for(ulong i = 0; icuttoff[i]) s[i] = 1./s[i]; else s[i] = 0.0; matrix mats = matrix::Zeros(s.Size(),1); mats.Col(s,0); matrix vm = multiply(u.Transpose(),s); return v.Transpose().MatMul(vm); } //+------------------------------------------------------------------+ //| shuffle elements of vector | //+------------------------------------------------------------------+ template vector shuffleVector(vector &in,CHighQualityRandStateShell* rstate=NULL) { vectorout(in.Size()); bool destroy = false; //--- if(rstate == NULL) { destroy = true; rstate = new CHighQualityRandStateShell(); CHighQualityRand::HQRndRandomize(rstate.GetInnerObj()); } //--- ulong k=0; ulong size=in.Size(); out=in; int error = 0; T tmp; //--- for(ulong i=0; i=size) k=size-1; //--- tmp = out[i]; out[i]=out[k]; out[k]=tmp; } //--- if(destroy) delete rstate; //--- return out; } //+------------------------------------------------------------------+ //| shuffle elements of vector | //+------------------------------------------------------------------+ template bool shuffleArray(T &in[],CHighQualityRandStateShell* rstate=NULL) { bool destroy = false; //--- if(rstate == NULL) { destroy = true; rstate = new CHighQualityRandStateShell(); CHighQualityRand::HQRndRandomize(rstate.GetInnerObj()); } //--- ulong k=0; uint size=in.Size(); int error = 0; T tmp; //--- for(ulong i=0; i=size) k=size-1; //--- tmp = in[i]; in[i]=in[k]; in[k]=tmp; } //--- if(destroy) delete rstate; //--- return true; } //+------------------------------------------------------------------+ //| shuffle elements of vector | //+------------------------------------------------------------------+ template matrix shuffleMatrix(matrix &in,bool by_rows=true,CHighQualityRandStateShell* rstate=NULL) { matrixout(in.Rows(), in.Cols()); bool destroy = false; //--- if(rstate == NULL) { destroy = true; rstate = new CHighQualityRandStateShell(); CHighQualityRand::HQRndRandomize(rstate.GetInnerObj()); } //--- ulong size=by_rows?in.Rows():in.Cols(); vector vec; out=in; //--- for(ulong i=0; i2) { vector xm = sliceVector(x,1,long(x.Size()-1)); vector xm_m1 = sliceVector(x,0,long(x.Size()-2)); vector xm_p1 = sliceVector(x,2); vector temp = (200.0 * (xm - pow(xm_m1,2.0)) - 400.0 * (xm_p1 - pow(xm,2.0)) * xm - 2.0 * (1.0 - xm)); if(!vectorCopy(grad,temp,1,long(grad.Size()-1))) return vector::Zeros(0); } grad[0] = -400.0 * x[0] * (x[1] - pow(x[0],2.0)) - 2.0 * (1.0 - x[0]); grad[grad.Size()-1] = 200.0 * (x[x.Size()-1] - pow(x[x.Size()-2],2.0)); return grad; } //+------------------------------------------------------------------+ //| Hessian matrix of the Rosenbrock function. | //+------------------------------------------------------------------+ matrix rosen_hess(vector &x) { vector x1 = sliceVector(x,0,long(x.Size()-1)); vector x2 = sliceVector(x,1,long(x.Size()-1)); vector x3 = vector::Zeros(x.Size()); matrix h1,h2,h3,H; if(!h1.Diag(-400.0*x1,1) || !h2.Diag(400.0*x1,-1)) { Print(__FUNCTION__, " error ", GetLastError()); return matrix::Zeros(0,0); } H = h1 - h2; x3[0] = 1200.0 * pow(x[0],2.0) - 400.0 * x[1] + 2.0; vector temp = 202.0 + 1200.0 * pow(x2,2) - 400.0 * sliceVector(x,2); x3[x3.Size()-1] = 200.0; if(!vectorCopy(x3,temp,1,long(x3.Size()-1))) return matrix::Zeros(0,0); if(!h3.Diag(x3)) { Print(__FUNCTION__, " error ", GetLastError()); return matrix::Zeros(0,0); } return H+h3; } } //+------------------------------------------------------------------+