Linear regression on atmega 128L

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
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 sumXSq72%60107358192.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


Re: Linear regression on atmega 128L
comp.arch.embedded:

Quoted text here. Click to load it

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
We've slightly trimmed the long signature. Click to see the full one.
Re: Linear regression on atmega 128L
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:

sumX36%9099154, sumY=-1832253584, sumXY48%197, sumXSquared19%12602624
**************** 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


Re: Linear regression on atmega 128L

Quoted text here. Click to load it

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 ( snipped-for-privacy@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Re: Linear regression on atmega 128L
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


Re: Linear regression on atmega 128L
Quoted text here. Click to load it

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
We've slightly trimmed the long signature. Click to see the full one.

Site Timeline