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

#21 KodeDaemon

KodeDaemon

    Advanced Member

  • Members
  • PipPipPip
  • 63 posts

Posted 12 April 2011 - 05:33 AM

These libraries use native code. I have not tested them for performance. The native code just wraps the library functions that come with RVDS. In theory the code may compile with GCC, I have not tested this. I can attach the code if people are interested. I just thought it might be easier this way since not everyone is able to compile the firmware.

@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



#22 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 12 April 2011 - 06:53 AM

I might be interested in it. I'd love having some serious signal proc lib to use with Netduino. At the moment is quite impossible, because there's no ability to sample data and work on values collected. I have already written/adapted a FFT in C#, but I'd like to port it to native code: either for performance, but also for memory occupation. The most complicated problem I would to solve is to write a kind of "sampler" that collect ADC data taken over a quite-precise period.
Biggest fault of Netduino? It runs by electricity.

#23 Jon Henry

Jon Henry

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 12 April 2011 - 12:08 PM

It seems like the cos function is fairly accurate up to 2pi. I wrote this piece of code that takes the input and scales it down to a comaparable angle below 2pi so the Math.Cos function can evaluate it.
public static double convRange(double x)
        {
            double temp = ((x / (2 * Math.PI)) - (int)(x / (2 * Math.PI))) * (2 * Math.PI);

            return temp;
        }

Using it IM able to get Math.Cos(convRange(257)) = 0.81930151916611216. Its much closer than before, accurate to a few decimal points.

#24 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 12 April 2011 - 12:48 PM

It seems like the cos function is fairly accurate up to 2pi. I wrote this piece of code that takes the input and scales it down to a comaparable angle below 2pi so the Math.Cos function can evaluate it.

public static double convRange(double x)
        {
            double temp = ((x / (2 * Math.PI)) - (int)(x / (2 * Math.PI))) * (2 * Math.PI);

            return temp;
        }

Using it IM able to get Math.Cos(convRange(257)) = 0.81930151916611216. Its much closer than before, accurate to a few decimal points.


I don't know how that function could be act as a "cosine".

Bear in mind that the sin/cos functions embedded in the MF take the integer argument in degrees and give an integer result from -1000 to 1000, inclusive. Clearly for performance reasons.
Biggest fault of Netduino? It runs by electricity.

#25 Michel Trahan

Michel Trahan

    Advanced Member

  • Members
  • PipPipPip
  • 155 posts

Posted 12 April 2011 - 01:10 PM

could you manage any way to cut-off the original MF math and insert the ours?

Or simply giving it to Microsoft to include in the .net mf framework ? Solving the problem, not patching it ?
Just a thought :)

And as a physicist ... I want a real math library ...
Started with C in 1985, moved to Vb3 ... to vb6 and stopped. Now started with .Net and learning C# and VB.net and wishing VB.net was on MF !

#26 Jon Henry

Jon Henry

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 12 April 2011 - 06:18 PM

I don't know how that function could be act as a "cosine".

Bear in mind that the sin/cos functions embedded in the MF take the integer argument in degrees and give an integer result from -1000 to 1000, inclusive. Clearly for performance reasons.

This function doesnt act as the cosine, it simlpy converts whatever angle I give it in radians to a comparable angle less than 2pi radians so that the Math.Cos function can use it. The library I was using is the Elzekool math library.

I still have to use the Math.Cos function like normal, I just put in a smaller value for the angle.

My original angle was 257 radians, the function I posted then converted that to 5.6725807189941353. Then I take the cosine of that, Math.Cos(5.6725807189941353). That gives me the approximate cos of 257.

My function doesnt replace the cosine function, it just creates a usable(acoording to the apparent constraints on this library) input for it.

#27 Rod Lopez

Rod Lopez

    Advanced Member

  • Members
  • PipPipPip
  • 33 posts
  • LocationSweden

Posted 12 April 2011 - 06:27 PM

Just a few ideas...
I had the same issue with the Math library (it being incomplete and somewhat not to spec), I decided to go for Elze Kool's, http://www.microframework.nl
That one is open and works like a charm.... with two modifications, one of them related to your Cos issue

FIX:
(line numbers)
195		public static double Cos(double x)
196		{
197		x = x % TwoPI;

that will enable you using values greater than 2*Pi for lookups, otherwise you end up with the exact same issue you had (insanely large values being returned)

The other issue was in the Atan funcion, which had its incoming values in the wrong order*
*"wrong" meaning swapped with respect to the standard atan2 math implementation, where one enters 'y' and then 'x'.

FIXED VERSION:
149		public static double Atan2(double y, double x)
150		{
151		
152		if ((y + x) == y)
153		{
154		if ((y == 0F) & (x == 0F)) return 0F;
155		
156		if (y >= 0.0F)
157		return pio2;
158		else
159		return (-pio2);
160		}
161		else if (x < 0.0F)
162		{
163		if (y >= 0.0F)
164		return ((pio2 * 2) - atans((-y) / x));
165		else
166		return (((-pio2) * 2) + atans(y / x));
167		
168		}
169		else if (y > 0.0F)
170		{
171		return (atans(y / x));
172		}
173		else
174		{
175		return (-atans((-y) / x));
176		}
177		}

Other than that that library works very well in general, there might be other issues though :)

PS: I could post these to a public repo so that other changes could be contributed, any interest on that?

#28 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 13 April 2011 - 03:44 AM

@Rod: of sure it works better, but I guess it would be really slow to evaluate. The original MF function is trivial, but is also blazing fast, because it is an integer division and a table lookup. In the Grommet source (the one you refer to), there are lot of double calculations: bear in mind that the MCU does not own a co-processor. I had an occasion to compare the performance of ints anf floats: they are almost the same. I'd suggest to implement either a function fully compatible with the MF, or using floats. Cheers
Biggest fault of Netduino? It runs by electricity.

#29 Rod Lopez

Rod Lopez

    Advanced Member

  • Members
  • PipPipPip
  • 33 posts
  • LocationSweden

Posted 13 April 2011 - 09:32 AM

@Mario: I had the understanding that floats and doubles were in the same perf neighbourhood for the Netduino (I've mostly seen HW dealing with one internal precision). If ints and floats are roughly as fast then, the Grommet library, should it be converted to floats (or rather a precision #def), would be a winner, is that assumption correct?

#30 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 13 April 2011 - 10:00 AM

Rod, probably you're mixing some concept (or I didn't understand well your comment). Let's point the types involved: int (aka Int32, signed-dword); float (aka Single, IEEE single-precision real, on 32 bit) double (aka Double, IEEE double-precision real, on 64 bit) I have written about the similar performance of int and float, not double! I haven't tested the double yet, but I guess they are much heavier than a 32 bit field. The Grommet lib uses double for the Cos function. More: it mixes floats and doubles in a strange manner. I don't know whether there is any goos reason for the MF, but on a PC has no sense. Since the MF on Netduino is very slow, I'd prefer to leave the integer version and/or a float one.
Biggest fault of Netduino? It runs by electricity.

#31 Rod Lopez

Rod Lopez

    Advanced Member

  • Members
  • PipPipPip
  • 33 posts
  • LocationSweden

Posted 13 April 2011 - 10:24 AM

Sorry for that, it was a mistake in my post. When I say

If ints and doubles are roughly as fast then

it should read

If ints and floats are roughly as fast then

I was talking about moving all the code to floats, not doubles :) (I fixed my post now)

#32 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 13 April 2011 - 11:56 AM

Perfect: no problem at all! The "other" problem is about what is the better solution. If we are going to give our solution to the MF team, they (reasonably) won't change the functions signature, because that will generate backward incompatibility (OK, maybe not a big deal). So, we should give them a better way to calculate Sin/Cos function using the same signature. Clear that the float would be the better compromise. 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.