Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Cosine function


  • Please log in to reply
31 replies to this topic

#1 Jon Henry

Jon Henry

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 10 April 2011 - 06:08 PM

When I run Math.Cos(257) I get an astronomically large number. 1.225.........e+20 Is this normal?

#2 KodeDaemon

KodeDaemon

    Advanced Member

  • Members
  • PipPipPip
  • 63 posts

Posted 10 April 2011 - 06:57 PM

When I run Math.Cos(257) I get an astronomically large number. 1.225.........e+20

Is this normal?


I'm not sure what that value is, it does not appear to be correct.

#3 Jon Henry

Jon Henry

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 10 April 2011 - 07:16 PM

I'm not sure what that value is, it does not appear to be correct.

The value equates to about 122,500,000,000,000,000,000.

Like I said up to about 10, its accurate. Anyone else encounter this?

#4 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 10 April 2011 - 07:48 PM

The value equates to about 122,500,000,000,000,000,000.

Like I said up to about 10, its accurate. Anyone else encounter this?

Given that cosinus swings between (and including) -1 and 1, makes 122,500,000,000,000,000,000 very wrong indeed. An angle of 257 radians should procuce a value of approx 0.81930552914498220005191005414538.

#5 Jon Henry

Jon Henry

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 10 April 2011 - 08:02 PM

Given that cosinus swings between (and including) -1 and 1, makes 122,500,000,000,000,000,000 very wrong indeed. An angle of 257 radians should procuce a value of approx 0.81930552914498220005191005414538.

Yep, but when I run it through the netduino, thats not what I get. Im on here to see if thats something other people see from their netduinos are if IM having some kind of problem. Imusing the cos function in other parts of my code with no problem. I am using muuch smaller numbers there though.

I just ran it in C# on a desktop and it worked as it should.

This is exactly what Im getting from the netduino: Math.Cos(257) = 1.2253809384034759e+20

#6 KodeDaemon

KodeDaemon

    Advanced Member

  • Members
  • PipPipPip
  • 63 posts

Posted 10 April 2011 - 08:29 PM

Yep, but when I run it through the netduino, thats not what I get. Im on here to see if thats something other people see from their netduinos are if IM having some kind of problem. Imusing the cos function in other parts of my code with no problem. I am using muuch smaller numbers there though.

I just ran it in C# on a desktop and it worked as it should.

This is exactly what Im getting from the netduino: Math.Cos(257) = 1.2253809384034759e+20


What code are you using to come to this value? The values returned from the NETMF Spot libraries are from -1000 to +1000. Which is the cosine of the angle in degrees multiplied by 1000 with quite a bit of precision removed. The value that I get when I run it is -309 or -0.309. The actual value should be -0.2249510543438649980511072083428.

#7 KodeDaemon

KodeDaemon

    Advanced Member

  • Members
  • PipPipPip
  • 63 posts

Posted 10 April 2011 - 08:35 PM

A couple of months ago I wrote a native math library to overcome the issues with the math library that comes with NETMF. I'll try and dig it up and post it here. It does require custom compiling the firmware.

#8 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 10 April 2011 - 09:03 PM

The value that I get when I run it is -309 or -0.309. The actual value should be -0.2249510543438649980511072083428.

I get the same results as KodeDaemon, namely -309, with the code below (in both the emulator and on the device). I also agree that it is not its expected value.

using Microsoft.SPOT;

namespace NetduinoApplication5 {
  public class Program {
    public static void Main() {
      Debug.Print("value="+Math.Cos(257));
    }
  }
}

Then I became curious as to why it is -309 rather than -225. Looking at the firmware source, I found the code in CLR/Libraries/SPOT/spot_native_Microsoft_SPOT_Math.cpp which references a big lookup table in CLR/Core/Core.cpp. This big lookup table stores sin and cos values for (degree/6)

Which will explain the output of this program:

using Microsoft.SPOT;

namespace NetduinoApplication5 {
  public class Program {
    public static void Main() {
      for(var i=255; i<=260; ++i) {
        Debug.Print("cos("+i+") = "+Math.Cos(i));
      }
    }
  }
}

Which has this output:
cos(255) = -309
cos(256) = -309
cos(257) = -309
cos(258) = -208
cos(259) = -208
cos(260) = -208

Note the discontinuity between cos(257) and cos(258). Seems rather lame to me. I believe this could be improved with a firmware change.

#9 Jon Henry

Jon Henry

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 10 April 2011 - 09:45 PM

public static double hdgCalc()
     {
         double pitch = 0;
      
         //other code

         pitch = Math.Cos(accel[0]); //accel[0] is equal to 257.tried actually putting 257 in place to confirm right numbers

         return pitch;

     }

This is being transmitted wirelessly back to my pc. All the transmission works perfectly, no errors there.

I tried debugging with your code Corey:

Debug.Print("value="+Math.Cos(257));

Im getting: Value=1.2253809384034759e+20

Tried the exMath library someone had posted on here and it yields the same result.

#10 KodeDaemon

KodeDaemon

    Advanced Member

  • Members
  • PipPipPip
  • 63 posts

Posted 10 April 2011 - 09:57 PM

I found the math library code I wrote. I have to change the namespace before I post the source here. I'll also do a custom firmware build too if anyone is interested.

#11 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 11 April 2011 - 01:48 AM

Hey Kode, If the built-in functions are wrong, we can also submit a fix back to Microsoft so that it's fixed on all platforms... When I spoke with them about the built-in math functions a few months ago, they weren't aware of any bugs in the math libraries. Chris

#12 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 11 April 2011 - 04:25 AM

Good hit, people!
Anyway there's nothing wrong in the MF code, except for an offset.
The problem is that the whole circle (where sin/cos are defined) is divided in 60 parts and the error is quite high, especially where the function derivative is higher.
Here is a small table built using values calculated by the MF and compared with the exact values:

Angle	MF.Sin	MF.Cos	Exact Sin	Exact Cos
0	0	1000	0	        1
1	0	1000	0,0174524067	0,9998476952
2	0	1000	0,0348994972	0,999390827
3	0	1000	0,052335957	0,9986295347
4	0	1000	0,0697564748	0,9975640502
5	0	1000	0,087155744	0,996194698
6	105	995	0,1045284648	0,9945218952
7	105	995	0,1218693452	0,9925461514
8	105	995	0,139173103	0,9902680685
9	105	995	0,1564344673	0,9876883402
10	105	995	0,1736481802	0,9848077526
11	105	995	0,1908089982	0,9816271829
12	208	978	0,2079116938	0,9781476001
13	208	978	0,2249510576	0,974370064
14	208	978	0,2419218991	0,9702957254
15	208	978	0,2588190488	0,9659258253
16	208	978	0,2756373598	0,9612616948
17	208	978	0,2923717089	0,9563047547
18	309	951	0,3090169988	0,9510565149
19	309	951	0,3255681591	0,945518574
20	309	951	0,3420201482	0,939692619
21	309	951	0,3583679546	0,9335804246
22	309	951	0,3746065987	0,9271838524
23	309	951	0,3907311339	0,9205048511
24	407	914	0,4067366487	0,9135454551
25	407	914	0,4226182676	0,9063077843
26	407	914	0,4383711528	0,8987940434
27	407	914	0,4539905059	0,891006521
28	407	914	0,4694715692	0,8829475895
29	407	914	0,4848096268	0,8746197035
30	500	866	0,5000000067	0,8660253999

The MF function takes the result of the division (0..59) to index a table: that is very simple and fast.
What is wrong is the angle rounding offset.
Take a look at the rows with angle 5 and 6. The result with an angle of 6 is right enough, but when 5 the error is huge.
Same thing for any table-index change: rows 11-12, rows 17-18, etc.
It would be better having the min error centered in the angle slot, that is having the min error when angle is 2-3, 8-9, 14-15, etc.

Anyway, that is a good bet!
I'll try to find a simple and fast function to calculate sin/cos better than the MF one's, then test the FFT. Shame on me, but I had not considered this side on the bad FFT result.
This is another reason to develop a serious signal and math library. ;)
Cheers
Biggest fault of Netduino? It runs by electricity.

#13 KodeDaemon

KodeDaemon

    Advanced Member

  • Members
  • PipPipPip
  • 63 posts

Posted 11 April 2011 - 05:37 AM

I wouldn't say bugs, but I would say that there is a fair amount of precision loss in the core libraries, which I believe would be expected by some users. Plus, not to mention the fact that it's missing a lot of functions.

#14 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 11 April 2011 - 11:56 AM

Im getting: Value=1.2253809384034759e+20

Tried the exMath library someone had posted on here and it yields the same result.

Have you played with the Netduino firmware?
Can't be only yours behaving similar.

Anyway, I have got a decent workaround, but using C# at the moment.
Here is a (messy) preview of the code (tested only on PC), that I will publish with some concrete result (also on Netduino):


static class HighfieldMath3
    {
        static HighfieldMath3()
        {
            //this will disappear on the actual release:
            //the array will have constant values
            for (int i = 0; i <= 90; i++)
            {
                var alfa = i * Math.PI / 180;
                _quarter[i] = (short)(Math.Sin(alfa) * 1000);
            }
        }

        private static short[] _quarter = new short[91];


        public static int Sin(int arg)
        {
            arg = arg % 360;
            if (arg < 0)
                arg += 360;

            if (arg < 180)
            {
                if (arg < 90)
                {
                    //angle 0..89
                    return _quarter[arg];
                }
                else
                {
                    //angle 90..179
                    return _quarter[180 - arg];
                }
            }
            else
            {
                if (arg < 270)
                {
                    //angle 180..269
                    return -_quarter[arg - 180];
                }
                else
                {
                    //angle 270..359
                    return -_quarter[360 - arg];
                }
            }
        }


        public static int Cos(int arg)
        {
            return Sin(arg + 90);
        }
    }

Some partial result (on PC)...
a long running loop evaluating both sin and cos, yields these results:
System.Math double using radians: 62 ms (the native .Net full framework);
the mine: 52 ms

I have another version taking only 42 ms, but eats both more ram and flash.

Drawbacks: the Cos function takes a little more to evaluate.

Cheers
Biggest fault of Netduino? It runs by electricity.

#15 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 11 April 2011 - 04:59 PM

Im getting: Value=1.2253809384034759e+20

I have no idea why are you getting this number. Are you getting it in the emulator as well? I assume it must be due to some version difference with what most of the rest of us are using.

#16 Jon Henry

Jon Henry

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 11 April 2011 - 10:46 PM

I have no idea why are you getting this number. Are you getting it in the emulator as well? I assume it must be due to some version difference with what most of the rest of us are using.

I havent used the emulator and frankly dont know where it is or how to use it. Im getting this result straight from the netduino.

#17 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 11 April 2011 - 11:22 PM

I havent used the emulator and frankly dont know where it is or how to use it.

Project properties -> .NET Micro Framework -> Transport (pull down and set to "Emulator")

then run your test program again

#18 Jon Henry

Jon Henry

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 11 April 2011 - 11:51 PM

Project properties -> .NET Micro Framework -> Transport (pull down and set to "Emulator")

then run your test program again


OK did some testing. The Math class I was using was one I had downloaded some time ago. Using it I was getting 1.2253809384034759e+20
Ive attached that class, dont remember where I got it.

I switched the cos function to the Microsoft.Spot.Math class and now Math.Cos(257) yields -309.

Attached Files

  • Attached File  Math.cs   17.58KB   5 downloads


#19 KodeDaemon

KodeDaemon

    Advanced Member

  • Members
  • PipPipPip
  • 63 posts

Posted 12 April 2011 - 05:15 AM

I'm attaching here the firmware files and the managed library for the math library I wrote. I was able to get the following results. Math.Cos(257) = 0.81930552914498223 Netduino Firmware: Attached File  Netduino_4.1.0.6.zip   287.05KB   5 downloads Netduino Plus Firmware: Attached File  NetduinoPlus_4.1.0.6.zip   370.41KB   5 downloads Managed Library: Attached File  KodeDaemon.NETMF.System.zip   2.19KB   10 downloads

#20 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 12 April 2011 - 05:28 AM

@KodeDaemon: Are your math lib sources open? Have you tested any of the functions for performance? (seems to me you're using double and that is heavy for Netduino) Could we join our efforts to build an unique lib, so that will substitute the original MF math? @Chris: Once we have a well-done library, could you manage any way to cut-off the original MF math and insert the ours? (Just to save space) Cheers
Biggest fault of Netduino? It runs by electricity.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.