NCX: ArrayMax, ArrayMin: unexpected values

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

NCX: ArrayMax, ArrayMin: unexpected values

Post by HaWe »

hi,
I have

Code: Select all

 float x[256], y[256], xmax, ymax, xmin, ymin;
all arrays have already values of [-0.5...+0.5] (out of a FFT calculation).

If I calculate the ArrayMax or ArrayMin, I always get 0 (zero) ...!

Code: Select all

  
  xmax=ArrayMax(x, NA, NA);
  xmin=ArrayMin(x, NA, NA);

  ymax=ArrayMax(y, NA, NA);
  ymin=ArrayMin(y, NA, NA);
  
  NumOut(0,56, xmax); // all zeros!
  NumOut(0,48, xmin);
  NumOut(0,40, ymax);
  NumOut(0,32, ymin);
what is faulty?
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: NCX: ArrayMax, ArrayMin: unexpected values

Post by mattallen37 »

Don't ArrayMax and ArrayMin return an integer? If your values are no more than .5, and no less than -.5, then doesn't it stand to reason that you would only get 0?
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

Re: NCX: ArrayMax, ArrayMin: unexpected values

Post by muntoo »

Just use this:

Code: Select all

float ArrayMaxf(float &src[], unsigned int idx = NA, unsigned int len = NA)
{
    if(len == NA)
    {
        len = ArrayLen(src);
    }
    
    if(len == 0)
        return(0xFFFFFFFF);

    float fmax = src[0];

    unsigned int offset = idx + len;

    for(unsigned int i = idx; i < offset; ++i)
        fmax = max(fmax, src[i]);

    return(fmax);
}
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NCX: ArrayMax, ArrayMin: unexpected values

Post by HaWe »

mattallen37 wrote:Don't ArrayMax and ArrayMin return an integer? If your values are no more than .5, and no less than -.5, then doesn't it stand to reason that you would only get 0?
the definition says "variant", not "int or "long"

Code: Select all

variant ArrayMax  ( const variant &  src[],  
  unsigned int  idx,  
  unsigned int  len   
 ) 
Is this a bug?
Last edited by HaWe on 02 Jul 2011, 20:43, edited 4 times in total.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NCX: ArrayMax, ArrayMin: unexpected values

Post by HaWe »

muntoo,
the values of ArrayMaxf are faulty - they show 0.182 although max is about 0.3.
Min is about -0.3
for ArrayMinf is doesnt work at all

Code: Select all

#define min(a,b) (a<b?a:b)

#define max(a,b) (a>b?a:b)

//--------------------------------------------

float ArrayMaxf(float &src[], unsigned int idx = NA, unsigned int len = NA)
{
    if(len == NA)
    {
        len = ArrayLen(src);
    }
    if(len == 0)
        return(0xFFFFFFFF);

    float fmax = src[0];

    unsigned int offset = idx + len;

    for(unsigned int i = idx; i < offset; ++i)
        fmax = max(fmax, src[i]);

    return(fmax);
}

//--------------------------------------------

float ArrayMinf(float &src[], unsigned int idx = NA, unsigned int len = NA)
{
    if(len == NA)
    {
        len = ArrayLen(src);
    }
    if(len == 0)
        return(0xFFFFFFFF);

    float fmin = src[0];

    unsigned int offset = idx + len;

    for(unsigned int i = idx; i < offset; ++i)
        fmin = min(fmin, src[i]);

    return(fmin);
}
This is the complete test code:

Code: Select all

// Fast Fourier Transformation for NXT
// version 1.0ß
// source for NXC
// tested with BricxCC 3.3.8.10
// orig. ANSI C source:
// http: //read.pudn.com/downloads92/sourcecode/graph/360640/work3/fft2.h__.htm
// modified by HaWe 2011
//
// user interface (display list + program control)
// BtnLeft  < scroll back/up array lines
// BtnRight > scroll fwd/down array lines
// BtnExit    toggle end/start of array
// BtnCenter  OK / quit

//--------------------------------------------------
// IO functions
//--------------------------------------------------

char LCDline[]={56,48,40,32,24,16,8,0};

#define printf1( _x, _y, _format1, _value1) { \
  string sval1 = FormatNum(_format1, _value1); \
  TextOut(_x, _y, sval1); \
}

inline bool btnhit(){
   return ( ButtonPressed(BTN1, false) || ButtonPressed(BTN2, false)
         || ButtonPressed(BTN3, false) || ButtonPressed(BTN4, false));
}

//--------------------------------------------------
// math
//--------------------------------------------------

#define min(a,b) (a<b?a:b)

#define max(a,b) (a>b?a:b)

//--------------------------------------------

float ArrayMaxf(float &src[], unsigned int idx = NA, unsigned int len = NA)
{
    if(len == NA)
    {
        len = ArrayLen(src);
    }
    if(len == 0)
        return(0xFFFFFFFF);

    float fmax = src[0];

    unsigned int offset = idx + len;

    for(unsigned int i = idx; i < offset; ++i)
        fmax = max(fmax, src[i]);

    return(fmax);
}

//--------------------------------------------

float ArrayMinf(float &src[], unsigned int idx = NA, unsigned int len = NA)
{
    if(len == NA)
    {
        len = ArrayLen(src);
    }
    if(len == 0)
        return(0xFFFFFFFF);

    float fmin = src[0];

    unsigned int offset = idx + len;

    for(unsigned int i = idx; i < offset; ++i)
        fmin = min(fmin, src[i]);

    return(fmin);
}

//--------------------------------------------------
// FFT
//--------------------------------------------------

const int ArrLen=256;
float x[ArrLen], y[ArrLen];


int FFT(int dir)
{
   long  nn,i,i1,j,k,i2,l,l1,l2;
   float c1,c2,tx,ty,t1,t2,u1,u2,z;

   /* Calculate the number of points */

   int m= log(ArrLen)/log(2);

   nn = 1;
   for (i=0;i<m;i++)
      nn *= 2;

   /* Do the bit reversal */
   i2 = nn >> 1;
   j = 0;
   for (i=0;i<nn-1;i++) {
      if (i < j) {
         tx = x[i];
         ty = y[i];
         x[i] = x[j];
         y[i] = y[j];
         x[j] = tx;
         y[j] = ty;
      }
      k = i2;
      while (k <= j) {
         j -= k;
         k >>= 1;
      }
      j += k;
   }

   /* Compute the FFT */

   ClearScreen();
   printf1(0,LCDline[0],"%s", "Computing FFT... ");

   c1 = -1.0;
   c2 = 0.0;
   l2 = 1;
   for (l=0;l<m;l++) {
      printf1(0,LCDline[1],"%d", l);
      l1 = l2;
      l2 <<= 1;
      u1 = 1.0;
      u2 = 0.0;
      for (j=0;j<l1;j++) {
         for (i=j;i<nn;i+=l2) {
            i1 = i + l1;
            t1 = u1 * x[i1] - u2 * y[i1];
            t2 = u1 * y[i1] + u2 * x[i1];
            x[i1] = x[i] - t1;
            y[i1] = y[i] - t2;
            x[i] += t1;
            y[i] += t2;
         }
         z =  u1 * c1 - u2 * c2;
         u2 = u1 * c2 + u2 * c1;
         u1 = z;
      }
      c2 = sqrt((1.0 - c1) / 2.0);
      if (dir == 1)
         c2 = -c2;
      c1 = sqrt((1.0 + c1) / 2.0);
   }

   /* Scaling for forward transform */
   if (dir == 1) {
      for (i=0;i<nn;i++) {
         x[i] /= nn;
         y[i] /= nn;
      }
   }
   printf1(0,LCDline[3],"%s", "FFT ready!");

   return(1);
}



void FillArray1() {
  int i;
  for (i=0; i<ArrLen; ++i) x[i]=1;

  for (i=0; i<ArrLen; ++i) y[i]=0;
}


void FillArray101(){
  int i;
  for (i=0; i<ArrLen; ++i) x[i]=1;
  for (i=10; i<20; ++i) x[i]=0;

  for (i=0; i<ArrLen; ++i) y[i]=0;
}


void FillArraySin() {    // single sin period: wavelength=32
  int i;
  for (i=0; i<ArrLen; ++i) x[i]=sin(i*PI*3600.0/(310.0*180.0));
  for (i=0; i<ArrLen; ++i) y[i]=0;
}


void FillArraySin2() {    // double sin periods: wavelength=16
  int i;
  for (i=0; i<ArrLen; ++i) x[i]=sin(i*PI*3600.0/(155.0*180.0));
  for (i=0; i<ArrLen; ++i) y[i]=0;
}


void ExtremizeArray() {
  int i;
  float xmax, ymax, xmin, ymin;

  xmax=ArrayMaxf(x, NA, NA);
  xmin=ArrayMinf(x, NA, NA);

  ymax=ArrayMaxf(y, NA, NA);
  ymin=ArrayMinf(y, NA, NA);
  
  NumOut(0,56, xmax);
  NumOut(0,48, xmin);
  NumOut(0,40, ymax);
  NumOut(0,32, ymin);

  while (!btnhit());
  ClearScreen();
  
  for (i=0; i<ArrLen; ++i) {
    if ((x[i]>0) && (x[i]<=xmax/10))  x[i]=0;
    if ((x[i]<0) && (x[i]>=xmin/10))  x[i]=0;
    if ((y[i]>0) && (y[i]<=ymax/10))  y[i]=0;
    if ((y[i]<0) && (y[i]>=ymin/10))  y[i]=0;
  }


}



void PrintArray2(string caption) {
   int i, j, k;
   char ExitBtnSwitchMode=1;    // toggle between ^home and ^end

   float  scale  = 1;
   string FmtStr = "%6.3f ";

   ClearScreen();
   printf1(0,LCDline[0], "%s", caption);
   printf1(0,LCDline[1], "%s", "idx  [x]    [y]");

   i=j=k=0;
   while(j<ArrLen) {
     k=0;
     for (i=0; i<6; ++i) {
       if (j<ArrLen) {
          printf1( 0, LCDline[i+2], "%d   ", j);
          printf1(18, LCDline[i+2], FmtStr, x[j]*scale);
          printf1(60, LCDline[i+2], FmtStr, y[j]*scale);
          ++k;
       }
       ++j;
     }
     if (k<5) {
       while (k<6) {
         printf1(0,LCDline[k+2], "%s", "                    ");
         ++k;
       }
     }

     while  (!btnhit());
     if (ButtonPressed(BTNLEFT, false)) {      // scroll back
       j=j-12;
       if (j<0) j=0;
       if (btnhit()) Wait(300);
     }
     else
     if (ButtonPressed(BTNRIGHT, false)) {     // scroll fwd
       if (j>ArrLen-5) j=ArrLen-5;
       if (j<0) j=0;
       if (j>=ArrLen-5) printf1(0,LCDline[7], "%s", "quit: BtnCenter ");
       if (btnhit()) Wait(300);
     }
     else
     if (ButtonPressed(BTNCENTER, false)) {    // quit
       while  (btnhit());
       if (j<ArrLen-1) j=j-6;
       if (j<0) j=0;
     }
     else
     if (ButtonPressed(BTNEXIT, false)) {      // last <-> first
       if (ExitBtnSwitchMode) {
         j=ArrLen-5;
         if (j<0) j=0;
         printf1(0,LCDline[7], "%s", "quit: BtnCenter ");
       }
       else {
         j=0;
        }
       ExitBtnSwitchMode^=1;
       while (btnhit());
     }

   }
   ClearScreen();
}

void PressToContinue(char Button) {
   string msg;
   if (Button==BTNCENTER)   msg="press BtnCntr...";
   else
   if (Button==BTNEXIT)     msg="press BtnExit...";
   else
   if (Button==BTNRIGHT)    msg="press BtnRight...";
   else
   if (Button==BTNLEFT)     msg="press BtnLeft...";

   printf1(0,LCDline[7],"%s", msg);
   while (!ButtonPressed(Button, false)); while (btnhit());
}


task main() {
   int i;
   char ch;

   SetAbortFlag(BTNSTATE_NONE);

   FillArraySin();  //  initialize by test values
   PrintArray2(" FillArraySin()");

   FFT(+1);  //  forward FFT

   //PressToContinue(BTNCENTER);

   PrintArray2(" FFT(+1) ");
   PressToContinue(BTNCENTER);
   
   ExtremizeArray();
   PrintArray2(" Extract 1 ");

   SetAbortFlag(BTNSTATE_PRESSED_EV);
   PressToContinue(BTNEXIT);
   
   while(1);

}
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NCX: ArrayMax, ArrayMin: unexpected values

Post by afanofosc »

It appears that the enhanced NBC/NXC firmware's ARROP opcode is a bit buggy. I am working on fixes to support arrays containing floating point values.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NCX: ArrayMax, ArrayMin: unexpected values

Post by afanofosc »

Please try the new test release (firmware and compiler changes) that should fix the problems described in this thread.

http://bricxcc.sourceforge.net/test_releases/

I have not updated the history.txt or bricxcc release notes or the help file yet. I will work on those this coming week.

Also in this release are a new JoystickMessageType structure and JoystickMessageRead API function that work with recently made enhancements to the BricxCC Joystick tool which allow you to change the tool from its default mode of directly controlling the motors to sending a message whenever motor direction and speed or joystick button states are changed.

Also in this release is support for the new RandomEx enhanced NBC/NXC firmware random number system call. This new system call is used when you target the enhanced firmware and you call the srand and rand functions.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NCX: ArrayMax, ArrayMin: unexpected values

Post by HaWe »

John, thx, I'll try it out immediately.

BTW: why do you permanently call your fw versions 1.31? Don't you have any other numbers on your keyboard? (if so I can send you one of mine via UPS^^)

on the other hand, maybe you wish to switch to Donald Knuth's system instead: "Version numbers of his TeX software approach the number π, in that versions increment in the style 3, 3.1, 3.14. 3.141, and so on. Similarly, version numbers of Metafont approach the base of the natural logarithm, e." (Wikipedia)
Last edited by HaWe on 03 Jul 2011, 14:39, edited 1 time in total.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NCX: ArrayMax, ArrayMin: unexpected values

Post by HaWe »

I tried it out:
files copied into programs\bricxcc
fw uploaded to NXT
code snippet:

Code: Select all

void ExtremizeArray() {
  int i;
  float xmax, ymax, xmin, ymin;

  xmax=ArrayMax(x, NA, NA);
  xmin=ArrayMin(x, NA, NA);

  ymax=ArrayMax(y, NA, NA);
  ymin=ArrayMin(y, NA, NA);
  
  printf1(0,56, "%s", "ArrayMax/Min");      // <<<<<<<<<<  TEST ArrayMax/Min
  printf1(0,40, "xmax=%6.3f", xmax);
  printf1(0,32, "xmin=%6.3f", xmin);
  printf1(0,24, "ymax=%6.3f", ymax);
  printf1(0,18, "ymin=%6.3f", ymin);

  while (!btnhit());
  ClearScreen();
  //...*SNIP*
}
edit:
confusing the fw versions... :evil:
why are they all named 1.31 ??? :evil: :evil: :evil:

now it's fine!
ArrayMax 0.jpg
ArrayMax 0.jpg (11.97 KiB) Viewed 8877 times
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NCX: ArrayMax, ArrayMin: unexpected values

Post by afanofosc »

I will probably someday increment the firmware version number. Please forgive me for not wanting to completely deviate from the version number of the standard firmware from which the enhanced firmware was created.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests