Forums

Linear regression on atmega 128L

Started by Intiha April 3, 2005
i,
Having found out that the avr-gcc lib supports floats and handles them
quite gracefully, I tried porting my linear regression code from
desktop on to the atmega 128L, more or less as is. For testing i used
the same table of X and Y values as sample inputs to the algorithm.

Now I am using microsecond granularity as input to the regression
engine and since the values are fairly large - and since there are sum
of products- I get fairly large numbers (If i do the same on my
desktop, the biggest number i get is sumXSq=7260107358192.000000).
Hence i decided to use long long (64 bit!) as follows:  (i know long
long and
int64_t are the same but i am clutching at straws)
typedef struct regressTbl{
	int16_t n ;
	long long sumXY;
	int64_t sumX,sumY;
	long long sumXSquared;
}regTable;

and then I added the sum for each point from the table. It should be
okay.. but it wasnt :( .. here is a manual version of the final values:


table.sumX = 12338578;
       table.sumY = -3336078;
       table.sumXSquared = 7260107358192; <-- 252
       table.sumXY = -1646741910392; <--- 253
        denom = ( table.n * table.sumXSquared - table.sumX *
table.sumX);
        if (denom != 0)
               a = (double)( table.n * table.sumXY - table.sumY *
table.sumX) / denom;
        b = (double)(table.sumY - a * table.sumX) / table.n;

     sprintf(OutputMsg,"sumX=%ld, sumY=%ld,
sumXY=%ld,sumXSquared=%ld\r\n",
table.sumX,table.sumY,table.sumXY,table.sumXSquared);
     UARTOutput(DBG_ERROR,"%s", &OutputMsg);
     sprintf(OutputMsg,"**************** A=%f     B=%f
***********\r\n",a,b);
     UARTOutput(DBG_ERROR,"%s", &OutputMsg);\

Here are the comile warnings:
Cricket.c:252: warning: integer constant is too large for "long" type
Cricket.c:253: warning: integer constant is too large for "long" type
Cricket.c:259: warning: long int format, different type arg (arg 3)
<-- Why these warnings?
Cricket.c:259: warning: long int format, different type arg (arg 4)
<--It prints something wrong as well :(

Is the above code doing something fundamentally beyond the capabilities
of avr-lib? Please tell me... i would appreciate the help.

regards
Affan

So what is wrong.. why isnt it accepting that latge values

On 3 Apr 2005 17:12:31 -0700, "Intiha" <intiha@gmail.com> wrote in
comp.arch.embedded:

> i, > Having found out that the avr-gcc lib supports floats and handles them > quite gracefully, I tried porting my linear regression code from > desktop on to the atmega 128L, more or less as is. For testing i used > the same table of X and Y values as sample inputs to the algorithm. > > Now I am using microsecond granularity as input to the regression > engine and since the values are fairly large - and since there are sum > of products- I get fairly large numbers (If i do the same on my > desktop, the biggest number i get is sumXSq=7260107358192.000000). > Hence i decided to use long long (64 bit!) as follows: (i know long > long and > int64_t are the same but i am clutching at straws) > typedef struct regressTbl{ > int16_t n ; > long long sumXY; > int64_t sumX,sumY; > long long sumXSquared; > }regTable; > > and then I added the sum for each point from the table. It should be > okay.. but it wasnt :( .. here is a manual version of the final values: > > > table.sumX = 12338578; > table.sumY = -3336078; > table.sumXSquared = 7260107358192; <-- 252 > table.sumXY = -1646741910392; <--- 253 > denom = ( table.n * table.sumXSquared - table.sumX * > table.sumX); > if (denom != 0) > a = (double)( table.n * table.sumXY - table.sumY * > table.sumX) / denom; > b = (double)(table.sumY - a * table.sumX) / table.n; > > sprintf(OutputMsg,"sumX=%ld, sumY=%ld, > sumXY=%ld,sumXSquared=%ld\r\n", > table.sumX,table.sumY,table.sumXY,table.sumXSquared); > UARTOutput(DBG_ERROR,"%s", &OutputMsg); > sprintf(OutputMsg,"**************** A=%f B=%f > ***********\r\n",a,b); > UARTOutput(DBG_ERROR,"%s", &OutputMsg);\ > > Here are the comile warnings: > Cricket.c:252: warning: integer constant is too large for "long" type > Cricket.c:253: warning: integer constant is too large for "long" type > Cricket.c:259: warning: long int format, different type arg (arg 3) > <-- Why these warnings? > Cricket.c:259: warning: long int format, different type arg (arg 4) > <--It prints something wrong as well :( > > Is the above code doing something fundamentally beyond the capabilities > of avr-lib? Please tell me... i would appreciate the help. > > regards > Affan > > So what is wrong.. why isnt it accepting that latge values
Next time please indicate the lines in the source code that the numbers in the error messages point to. It looks like your compiler is not completely C99 conforming and supports the 64-bit long long type as some sort of extension. A conforming C99 compiler will automatically make literal constants long long if they are too large to fit in a long. I'm not familiar with the avr-gcc port, but you could try making your constants explicitly long long with the LL suffix. That is: table.sumXSquared = 7260107358192LL; -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
Thank oyu for your reply.... I actually did point to the lines ( like
this <--252).
That explicit declaration of the literal did help- i tremoves the
warnings, however the calcualtion of 'a' and 'b' are still in correct.

  denom = ( table.n * table.sumXSquared - table.sumX *table.sumX);
        if (denom != 0)
               a = (double)( table.n * table.sumXY - table.sumY
*table.sumX) / denom;
        b = (double)(table.sumY - a * table.sumX) / table.n;

I have checked separately the result for a = -0.000208 , and b =
-133340.419011 (for the above equation and the hard coded values of the
variables). While what i get out of my serial port (is
sprintf(OutputMsg," A=%f     B=%f\r\n",a,b); sufficient when a,b and
denom have been declared as doubles? - or is it just a printing error?)
is:

sumX=369099154, sumY=-1832253584, sumXY=48197, sumXSquared=1912602624
**************** A=-0.045255     B=-106838.632813 ***********

Notice that the sumX are also being printed incorrect but I think they
are the direct result of me not specifying the correct specified for
long long ; since my compiler for %ld expects only long integer and
gives warning.

So is there something wrong with the simple division going on for
calculating a? I am thinking of using ldiv, if all else fails but it
would be infinitely better if the above just works.

I really appreciate you help.
Regards
Affan

Intiha <intiha@gmail.com> wrote:

> Notice that the sumX are also being printed incorrect but I think > they are the direct result of me not specifying the correct > specified for long long; since my compiler for %ld expects only > long integer and gives warning.
Well, then don't do that. Give it the correct format specifier for long long, or print the number split up into 2 32-bit longs. There's absolutely no sense in trying to debug results as long as you don't really know what the inputs were. -- Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de) Even if all the snow were burnt, ashes would remain.
thats the problem... I have gone throught avr-libc manual and the
closest it come to (for vprintf) is to use %ld or %li for long int
types... nothing for long long- Does any one know the correct flag?..
but i will try and get the split 32 bit values as soon as i get to the
office.

Regards
Affan

Intiha wrote:
> > thats the problem... I have gone throught avr-libc manual and the > closest it come to (for vprintf) is to use %ld or %li for long int > types... nothing for long long- Does any one know the correct flag?.. > but i will try and get the split 32 bit values as soon as i get to > the office.
Please quote enough of whatever you are replying to to provide a context. Your article should stand on its own. To do this on the broken google interface, see my sig lines below. long long is a C99 creation. Are you sure your AVR library is C99 compliant? I rather doubt it. gcc may well accept a -std=c99, but it won't help without the library. -- "If you want to post a followup via groups.google.com, don't use the broken "Reply" link at the bottom of the article. Click on "show options" at the top of the article, then click on the "Reply" at the bottom of the article headers." - Keith Thompson