8th September 2024

Lets open up ms paint and draw a cluster .

That is an upscale picture of a 60×60 manually drawn bmp file

This file will likely be fed into our code and the code must remodel it in order that the

route with the largest variance sits on the x axis (if i understood issues proper).

So , some preliminary stuff , open the file , useful resource it , learn the pixels , flip them to samples.

Our samples will appear to be this , we now have one class , no fancy stuff.

      class a_sample{
            public:
            int x,y,cluster;
            double xd,yd;             a_sample(void){x=0;y=0;cluster=0;}
            };

Ignore the cluster studying it was meant for an additional check -which failed-

These are the inputs we’ll be working with :

#embrace <CanvasCanvas.mqh>;
enter string testBMP="test_2.bmp";
enter shade fillColor=C'255,0,0';
enter shade BaseColor=clrWheat;
enter bool RemoveCovariance=false;

We learn the picture and switch every pixel that’s purple (or that matches our shade enter) to a pattern.

  if(ResourceCreate("TESTRESOURCE","Recordsdata"+testBMP)){
  uint pixels[],width,peak;
  if(ResourceReadImage("::TESTRESOURCE",pixels,width,peak)){
    
      int total_samples=0;
      uint seize=ColorToARGB(fillColor,255);
      ArrayResize(samples,width*peak,0);
      
        originalX=(int)width;
        originalY=(int)peak;
        int co=-1;         for(int y=0;y<(int)peak;y++){
           for(int x=0;x<(int)width;x++){
              co++;
              if(pixels[co]==seize){
                total_samples++;
                samples[total_samples-1].x=x;
                samples[total_samples-1].y=y;
                samples[total_samples-1].xd=x;
                samples[total_samples-1].yd=y;
                }
              }
           }
      ArrayResize(samples,total_samples,0);
      Print("Discovered "+IntegerToString(total_samples)+" samples");
}
}

Neat , now we cross the samples right into a matrix that’s scaled with every pattern being a row and every characteristic (x,y) being a column

           matrix unique;
                  unique.Init(total_samples,2);                     
                  for(int i=0;i<total_samples;i++){
                  unique[i][0]=samples[i].xd;
                  unique[i][1]=samples[i].yd;
                  } 

So we form (resize) the matrix to have complete samples # of rows and a couple of columns (x , y) . X+Y are our pattern options on this instance.

We then assemble , properly not we however the mq library costructs the covariance matrix , we cross false within the parameter as our options sit on the columns . The place our options on the rows , i.e. one row was one characteristic then we might name this operate utilizing true.

matrix covariance_matrix=unique.Cov(false);

What’s the covariance matrix ? it’s a options by options (options x options) (2×2) matrix that measures the covariance of every characteristic to all different options . Neat that we will use one line of code .

Then we want the eigenvectors and eigenvalues of that 2×2 covariance matrix

The idea i do not fairly understands states that this can point out the “route” of most “variance”.

Let’s play alongside 

           matrix eigenvectors;
           vector eigenvalues;
           if(covariance_matrix.Eig(eigenvectors,eigenvalues)){
           Print("Eigenvectors");
           Print(eigenvectors);
           Print("Eigenvalues");
           Print(eigenvalues);
           }else{Print("Cannot Eigen");}

the eigenvectors will likely be a 2×2 matrix as properly  if i am not mistaken , identical because the covariance martix.

Now , let’s take our samples and “flip” them in order that essentially the most various route sits on the x axis.If that is the way it works and it was not random.

Visualize what we predict to see right here based mostly on the primary picture posted.

That is how , to date : 

                      for(int i=0;i<total_samples;i++){
              vector thissample={samples[i].xd,samples[i].yd};
              thissample=thissample.MatMul(eigenvectors);
              samples[i].xd=thissample[0];
              samples[i].yd=thissample[1];
              }

I am setting up a vector that’s one pattern , so 2 components then matrix multiply it with the eigenvectors matrix then cross the ensuing x and y again to the samples .

Then some transformation once more , the reason being there’s to accommodate a number of eigenvector passes , you in all probability will get the identical concept.

                        double minX=INT_MAX,maxX=INT_MIN,minY=INT_MAX,maxY=INT_MIN;
             for(int i=0;i<total_samples;i++){
                if(samples[i].xd>maxX){maxX=samples[i].xd;}
                if(samples[i].xd<minX){minX=samples[i].xd;}
                if(samples[i].yd>maxY){maxY=samples[i].yd;}
                if(samples[i].yd<minY){minY=samples[i].yd;}
                }
                            double rangeX=maxX-minX;
               double rangeY=maxY-minY;
               double allMax=MathMax(maxX,maxY);
               double allMin=MathMin(minX,minY);
               double allRange=allMax-allMin;
               for(int i=0;i<total_samples;i++){
                  samples[i].xd=((samples[i].xd-minX)/rangeX)*1000.0;
                  samples[i].yd=((samples[i].yd-minY)/rangeY)*1000.0;
                  samples[i].x=(int)samples[i].xd;
                  samples[i].y=(int)samples[i].yd;
                  }
               originalX=1000;
               originalY=1000;

Then the drawing half which isn’t that vital .

that is the end result 


 

The samples touching the sides is extra because of our reconstruction however the transformation occured.

Right here is the complete code , i’ve left my errors in commented out , and likewise the removeCovariance will not be working.

Should you discover points let me know.

Now think about you may have 1000 options proper ? you can’t plot all that so how will we assemble a brand new characteristic that could be a artificial weighted sum of the outdated options based mostly on the eigenvectors (if i am heading in the right direction right here) . Like Precept element evaluation .

#property model   "1.00"
#embrace <CanvasCanvas.mqh>;
enter string testBMP="test_2.bmp";
enter shade fillColor=C'255,0,0';
enter shade BaseColor=clrWheat;
enter bool RemoveCovariance=false;
string system_tag="TEST_";
      class a_sample{
            public:
            int x,y,cluster;
            double xd,yd;             a_sample(void){x=0;y=0;cluster=0;}
            };
int DISPLAY_X,DISPLAY_Y,originalX,originalY;
double PIXEL_RATIO_X=1.0,PIXEL_RATIO_Y=1.0;
bool READY=false;
a_sample samples[];
CCanvas DISPLAY;
int OnInit()
  {
  ArrayFree(samples);
  DISPLAY_X=0;
  DISPLAY_Y=0;
  originalX=0;
  originalY=0;
  PIXEL_RATIO_X=1.0;
  PIXEL_RATIO_Y=1.0;
  READY=false;
  ObjectsDeleteAll(ChartID(),system_tag);
  EventSetMillisecondTimer(44);   ResourceFree("TESTRESOURCE");
  return(INIT_SUCCEEDED);
  } void OnTimer(){
EventKillTimer();   if(ResourceCreate("TESTRESOURCE","Recordsdata"+testBMP)){
  uint pixels[],width,peak;
  if(ResourceReadImage("::TESTRESOURCE",pixels,width,peak)){
    
      int total_samples=0;
      uint seize=ColorToARGB(fillColor,255);
      ArrayResize(samples,width*peak,0);
      
        originalX=(int)width;
        originalY=(int)peak;
        int co=-1;         for(int y=0;y<(int)peak;y++){
           for(int x=0;x<(int)width;x++){
              co++;
              if(pixels[co]==seize){
                total_samples++;
                samples[total_samples-1].x=x;
                samples[total_samples-1].y=y;
                samples[total_samples-1].xd=x;
                samples[total_samples-1].yd=y;
                }
              }
           }
      ArrayResize(samples,total_samples,0);
      Print("Discovered "+IntegerToString(total_samples)+" samples");
      
        
        
            
           matrix unique;
                  unique.Init(total_samples,2);                     
                  for(int i=0;i<total_samples;i++){
                  unique[i][0]=samples[i].xd;
                  unique[i][1]=samples[i].yd;
                  }             
                    matrix covariance_matrix=unique.Cov(false);
           Print("Covariance matrix");
           Print(covariance_matrix);
           matrix eigenvectors;
           vector eigenvalues;
           matrix inverse_covariance_matrix=covariance_matrix.Inv();
           if(covariance_matrix.Eig(eigenvectors,eigenvalues)){
           Print("Eigenvectors");
           Print(eigenvectors);
           Print("Eigenvalues");
           Print(eigenvalues);
                      for(int i=0;i<total_samples;i++){
              vector thissample={samples[i].xd,samples[i].yd};
              thissample=thissample.MatMul(eigenvectors);
              samples[i].xd=thissample[0];
              samples[i].yd=thissample[1];
              if(RemoveCovariance){
                samples[i].xd/=MathSqrt(eigenvalues[0]);
                samples[i].yd/=MathSqrt(eigenvalues[1]);
                }
              
              }
                                   double minX=INT_MAX,maxX=INT_MIN,minY=INT_MAX,maxY=INT_MIN;
             for(int i=0;i<total_samples;i++){
                if(samples[i].xd>maxX){maxX=samples[i].xd;}
                if(samples[i].xd<minX){minX=samples[i].xd;}
                if(samples[i].yd>maxY){maxY=samples[i].yd;}
                if(samples[i].yd<minY){minY=samples[i].yd;}
                }
                            double rangeX=maxX-minX;
               double rangeY=maxY-minY;
               double allMax=MathMax(maxX,maxY);
               double allMin=MathMin(minX,minY);
               double allRange=allMax-allMin;
               for(int i=0;i<total_samples;i++){
                  samples[i].xd=((samples[i].xd-minX)/rangeX)*1000.0;
                  samples[i].yd=((samples[i].yd-minY)/rangeY)*1000.0;
                  
                  samples[i].x=(int)samples[i].xd;
                  samples[i].y=(int)samples[i].yd;
                  }
               originalX=1000;
               originalY=1000;
           }else{Print("Can't eigen");}          
      
      build_deck(originalX,originalY);
      READY=true;
    }else{
    Print("Can't learn picture");
    }
  }else{
  Print("Can't load file");
  }
ExpertRemove();
Print("DONE");
} void build_deck(int img_x,
                int img_y){   int screen_x=(int)ChartGetInteger(ChartID(),CHART_WIDTH_IN_PIXELS,0);
  int screen_y=(int)ChartGetInteger(ChartID(),CHART_HEIGHT_IN_PIXELS,0);   int btn_height=40;
  screen_y-=btn_height;   double img_x_by_y=((double)img_x)/((double)img_y);
  
    int test_x=screen_x;
    int test_y=(int)(((double)test_x)/img_x_by_y);
    if(test_y>screen_y){
    test_y=screen_y;
    test_x=(int)(((double)test_y)*img_x_by_y);
    }   int px=(screen_x-test_x)/2;  
  int py=(screen_y-test_y)/2;
DISPLAY.CreateBitmapLabel(ChartID(),0,system_tag+"_display",px,py,test_x,test_y,COLOR_FORMAT_ARGB_NORMALIZE);
DISPLAY_X=test_x;
DISPLAY_Y=test_y;
DISPLAY.Erase(0);
PIXEL_RATIO_X=((double)(DISPLAY_X))/((double)(img_x));
PIXEL_RATIO_Y=((double)(DISPLAY_Y))/((double)(img_y));
PIXEL_RATIO_X=MathMax(1.0,PIXEL_RATIO_X);
PIXEL_RATIO_Y=MathMax(1.0,PIXEL_RATIO_Y); PIXEL_RATIO_X=8.0;
PIXEL_RATIO_Y=8.0;
update_deck();
} void update_deck(){
DISPLAY.Erase(ColorToARGB(clrBlack,255));
uint BASECOLOR=ColorToARGB(BaseColor,255);   for(int i=0;i<ArraySize(samples);i++){
  double newx=(((double)samples[i].x)/((double)originalX))*((double)DISPLAY_X);
  double newy=(((double)samples[i].y)/((double)originalY))*((double)DISPLAY_Y);
  int x1=(int)MathFloor(newx-PIXEL_RATIO_X/2.00);
  int x2=(int)MathFloor(newx+PIXEL_RATIO_X/2.00);
  int y1=(int)MathFloor(newy-PIXEL_RATIO_Y/2.00);
  int y2=(int)MathFloor(newy+PIXEL_RATIO_Y/2.00);
  DISPLAY.FillRectangle(x1,y1,x2,y2,BASECOLOR);
  }
DISPLAY.Replace(true);
ChartRedraw();
} void OnDeinit(const int purpose)
  {  
  }
void OnTick()
  {
  }

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.