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
Linear regression on atmega 128L
Started by ●April 3, 2005
Reply by ●April 3, 20052005-04-03
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 valuesNext 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
Reply by ●April 4, 20052005-04-04
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
Reply by ●April 4, 20052005-04-04
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.
Reply by ●April 4, 20052005-04-04
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
Reply by ●April 4, 20052005-04-04
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