ArrayMinimum and ArrayMaximum not working for me, incorrect values, even returns reversed min/max values.

 

Hi,

I'm having some issues with array sorting and ArrayMinimum() and ArrayMaximum().  Not sure if it is Update related or ME related.

I'll stick to the basic issue for this post - Min and Max are not returning correct values for me.  Notice the printout below. The minimum is zero rather than -1.0 and the Maximum printed out 8 rather than 99.0


Prior to this, on other tests using other arrays, it was even reversing the min and max returned values. Notice the 2nd printout at the bottom, showing the min as 499929 and max as 0. This was  after a sort. 

Prior to that I was unable to  get negatives to return under certain conditions such as after a sort.

Any help or suggestions as to how I can find what I'm doing wrong will be appreciated.


P.S.The documentation just confused things ever further for me. Notice the last block of code, look to the bottom of it and see the "output" which was supposed to be sorted. It is not sorted correctly imo. That code is from the MQL4 reference documentation under ArraySort.

Thanks

John

double Aarray[10]= {-1.0,2.0,3.0,4.0,5.0,6.0,7.0,9.0,99.0};
Print("minnn1   ",DoubleToStr(ArrayMinimum(Aarray,WHOLE_ARRAY,0),3));
Print("minnmaxn1   ",DoubleToStr(ArrayMaximum(Aarray,WHOLE_ARRAY,0),3));


0    16:08:31    2013.11.12 23:59  ea.mt4.ts.10.23 EURUSD,M1: minnn1   0.000

0    16:08:31    2013.11.12 23:59  ea.mt4.ts.10.23 EURUSD,M1: minnmaxn1   8.000



ArraySort(AEntryB, WHOLE_ARRAY,0,MODE_DESCEND);//sorts all, by P/L
Print("minnn2   ",ArrayMinimum(AEntryB,WHOLE_ARRAY,0));
Print("minnmaxn2   ",ArrayMaximum(AEntryB,WHOLE_ARRAY,0));

0    16:08:31    2013.11.12 23:59  ea.mt4.ts.10.23 EURUSD,M1: minnn2   499929
0    16:08:31    2013.11.12 23:59  ea.mt4.ts.10.23 EURUSD,M1: minnmaxn2   0

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- example of sorting of one dimensional array
   double num_array[5]={4,1,6,3,9};
//--- now array contains values 4,1,6,3,9
   ArraySort(num_array);
//--- now array is sorted 1,3,4,6,9
   ArraySort(num_array,WHOLE_ARRAY,0,MODE_DESCEND);
//--- now array is sorted 9,6,4,3,1
 
//--- example of sorting of two dimensional array
   int  DataArray[5][2]={{7,3},{3,1},{57,14},{12,4},{11,1}};
//--- sorting of DataArray[][] by first dimension  (ascending)
   ArraySort(DataArray,WHOLE_ARRAY,0,MODE_ASCEND);
//--- print sorted array
   for(int i=0; i<5; i++)
     {
      string str="index "+IntegerToString(i)+": ";
      for(int j=0; j<2; j++)
        {
         if(j==0) str+="{"; else str+=",";
         str+=IntegerToString(DataArray[i,j]);
         if(j==1) str+="}";
        }
      Print(str);
     }
//--- output
//index 0: {3,1}
//index 1: {7,3}
//index 2: {11,1}
//index 0: {3,1}
//index 4: {57,14}
  }
 
researchpro:

Hi,

I'm having some issues with array sorting and ArrayMinimum() and ArrayMaximum().  Not sure if it is Update related or ME related.

I'll stick to the basic issue for this post - Min and Max are not returning correct values for me.  Notice the printout below. The minimum is zero rather than -1.0 and the Maximum printed out 8 rather than 99.0

Those functions return the index (not the value) of the element with the highest/lowest value.

So ArrayMinimum returned 0 because Aarray[0] = -1

And ArrayMaximum returned 8 because Aarray[8]=99 

 
honest_knave:

Those functions return the index (not the value) of the element with the highest/lowest value.

So ArrayMinimum returned 0 because Aarray[0] = -1

And ArrayMaximum returned 8 because Aarray[8]=99 

Thanks honest_knave, 

A day well spent, just the same, as long as the answer came at the end of it...  

I just found a thread that stated the same thing too. Thanks for your speedy reply.

John 

 
No problem, I'm glad you got it sorted.
 

As a follow up.

The other issue mentioned was not returning negatives after a sort. It turns out that when sorting positives and negatives in the same array, the empty element values are treated as zeros, so a sort will send your positives to one end of the array and negatives to the opposite end, leaving the middle of the array empty(with zero's). In effect it split's your data into two halve's, unless your entire array is populated with input data.  Even if you limit the amount of elements to sort , to include only your input data, it still splits the positive/negative data up to both ends of the array spectrum.  Which means I have to covert to a dynamic array and resize it. Resizing a 2D array, is giving me problems too

 It stated that I needed a Type to resize, so I did double. but now it tells me:   ';' -missing')' before';'

So I'm unable to declare a Type to resize it. 

 What is the correct way and place to ArrayResize() ? I am tying it on the Global level. Please show example if possible.

Note, in the documentation example it did not need a Type to resize (see last block of code from documentation example below) Though when I try it, I get a error stating I need a Type.

 

 Thanks

double AEntryB[][40];
double ArrayResize(AEntryB,500000);

 

//--- An array for demonstration of a quick version
   double arr[];
   ArrayResize(arr,100000,100000);

 

John 

 

final outcome, I had to resize initially in Start(). and declare the 2D array globally.

To solve the problem of sorting both positive and negative numbers in the same row, I first had to sort by a different row, which was all positive. Then I could resize my array, because all the values were at one end of the array.

Then I switch the value positions inside the array putting the Neg and Pos values, back up top, and resort. Works great, and only took the entire day and night.  

John 

 
researchpro:

the empty element values are treated as zeros,

so a sort will send your positives to one end of the array and negatives to the opposite end, leaving the middle of the array empty(with zero's).

Even if you limit the amount of elements to sort , to include only your input data, it still splits the positive/negative data up to both ends of the array spectrum.  Which means I have to covert to a dynamic array and resize it.

Resizing a 2D array, is giving me problems too

It stated that I needed a Type to resize, so I did double. but now it tells me:   ';' -missing')' before';'

double ArrayResize(AEntryB,500000);

So I'm unable to declare a Type to resize it. 

 What is the correct way and place to ArrayResize() ? I am tying it on the Global level. Please show example if possible.

  1. An array has no empty elements. It has what ever you last put there or zero.
  2. That's called sorting. What do you expect?
  3. False. If the array contains { 1, 2, -1, -2, 0, 0} and you call sort with a size of 4, you get {-2, -1, 1, 2, 0, 0}
  4. ArrayResize() is a function. You do not give it a type, you call it inside of your functions. You can't call it globablly.
    double AEntryB[][40];
    
    void OnStart(){
      ArrayResize(AEntryB,500000);
    }

 
WHRoeder:
researchpro:

the empty element values are treated as zeros,

so a sort will send your positives to one end of the array and negatives to the opposite end, leaving the middle of the array empty(with zero's).

Even if you limit the amount of elements to sort , to include only your input data, it still splits the positive/negative data up to both ends of the array spectrum.  Which means I have to covert to a dynamic array and resize it.

Resizing a 2D array, is giving me problems too

It stated that I needed a Type to resize, so I did double. but now it tells me:   ';' -missing')' before';'

So I'm unable to declare a Type to resize it. 

 What is the correct way and place to ArrayResize() ? I am tying it on the Global level. Please show example if possible.

  1. An array has no empty elements. It has what ever you last put there or zero.
  2. That's called sorting. What do you expect?
  3. False. If the array contains { 1, 2, -1, -2, 0, 0} and you call sort with a size of 4, you get {-2, -1, 1, 2, 0, 0}
  4. ArrayResize() is a function. You do not give it a type, you call it inside of your functions. You can't call it globablly.

Thanks WHRoeder,

#1 When I sorted my 500,000 static array, containing only 1500 values in the top row, it sent the positives to the left and the negatives to the right. At least that is how it printed, unless I somehow was mistaken.  The only explanation I could think of was that it was counting empty elements as zero's.  So in the 0 element it would have the highest positive value and in the 500000 element it would have the lowest negative value. It is why I could not get my negatives to return, only the positives after sorting. I even tried only sorting the 1500 elements that I had populated., rather than WHOLE_ARRAY.   I want to make sure I am understanding it correctly so I will test more carefully. If I am misunderstanding it, then it will mess me up in the future. 

 

Thanks for the info, I will post my test results.

John 

 

Okay, I pretty much re-created the issue I was having so that it can be seen what is occurring and why I concluded that the Sort function splits Positive and negative data and sends it to opposite ends of the array spectrum.

I will post the pertinent section of code. ( I can't post it all a due to 6000 lines  of interconnected logic. But I wanted to use the actual code so that if I'm making a mistake it can be discovered)

Here is what the code does, Array Row 0 has all positive values and row 37 has both Pos and Neg. I switched the row values in the first loop, sending the Pos/Neg to the top row, so that I could sort by their values.

It prints the values while looping, so that you can see the pos and neg values and their element positions.

After that loop, I sort the array (by Pos/Neg values) and print again, in  a loop, usiing the same amount of increments that was counted during the 1st loop.

The negative values did not print up, instead it returned zeros where the negatives were supposed to be.

I made one more loop to print the opposite end of the array where the negative numbers wound up. I printed 50 of them in the loop.

Then I printed the array size so that it can be seen to be 500000 wide.

Then I limited the size of the sort, to populated elements only, and re-ran the test..

and this time it worked. It kept all values to one end of the array Pos and neg. 


My Conclusion, when sorting WHOLE_ARRAY it counts empty elements as Zeros, and splits your values in two, positive and negative to each opposite end of the array, leaving  zeros (empty elements) in the middle. This is clear on the printout.

When limiting the sort to populated elements, rather than WHOLE_ARRAY, it does not split the values in two and keeps Pos and Neg together, keeping them to the same side of the array.

 I've attached a note pad file showing the printouts of both tests.


Any correction is welcome. 

Thanks

John

      double Temp1;
     for(i=0;i<pop+10;i++){ // switches row elements 0 and 37 (positive values and pos/neg values, for sorting by pos/neg)
      if (AEntryB[i][0]>0){
       Temp1 = AEntryB[i][0];//= PositionProfit;
       AEntryB[i][0] = AEntryB[i][37];
       AEntryB[i][37] = Temp1;//= PositionProfit;

       Print("Pre Sort Print out","  i  = ",i,"  ",AEntryB[i][0]," temp    ",AEntryB[i][37],"  ",arraycounter);

       }  
      }
     ArraySort(AEntryB, WHOLE_ARRAY,0,MODE_DESCEND);
  
for(i=0;i<=arraycounter;i++){
 Print(" i= ",i,"   Top Row of Array =  ", AEntryB[i][0]);
}
for(i=499950;i<=500000;i++){  
 Print("Print out opposite end of Arrary where negatives were sent to ",AEntryB[i][0]);
}

Print("Array size 500000 x 40) = ",ArraySize(AEntryB));
Files:
Reason: