### Transcendental Two [updated]

There's a piece of historical baggage in the definition of sin/cos that is much older than just "whatever the 8087 chip happened to do": why are the sin and cos functions defined based on parameters that are periodic in a transcendental number? Having the period be 2\*pi is based on decades (centuries!) of mathematical standard practice. This whole problem with sin and cos would go away if only the period had a nice clean representation in floating point. For example, either degrees or turns (1 turn == 360 degrees) would be great. In particular, if the parameter to sin/cos were turns then argument reduction would be easy: just throw away the integer bits. Then you could do a table lookup based on extracting mantissa bits.

What is especially ironic is that if you grep through piles of source code you'll find a huge number of calls that look roughly like sin(angle\*(2\*Math.PI/360)). This has a necessarily slightly inaccurate value of pi, which is likely to be exactly the same value as the one in the 8087's sin/cos implementation - the two errors come pretty close to canceling since the argument is divided by the value of pi used in the implementation of sin/cos.

Update: Yes, I understand that there are lots of deep, important mathematical reasons that sincos are defined in terms of 2\*pi. The point I was trying to make is that if you peel open the covers of an implementation of sin/cos, 2\*pi is a very difficult period to cope with. At the same time, if you look at software that uses sin/cos, you'll find that a huge fraction of them use something other than 2\*pi (degrees are real common), and convert when invoking sin/cos.

(Mon Aug 01 09:11:44 PDT 2005)

As I recall it boils down to something like that a lot of early computer scientists were originally electronic engineers. For various reasons (one of which might be that all university level electronics lecturers are evil) in university level electronics courses frequencies are dealt with in radians per second rather than Hz (turns per second) and phase shifts in radians rather than degrees. [angle in degrees] \*(2PI/360) = [angle in radians] hence the early computer scientists, when they wrote the specs for for sin and cos, used radians rather than degrees. The upshot of this is that the rest of us (who use sane measures) have to convert to radians.

Posted by Stephen Booth on August 01, 2005 at 07:09 AM PDT #

Too geeky ..... keep it simple.

Posted by simpleguy on August 01, 2005 at 10:43 AM PDT #

Most of the time I really enjoy reading Gosling's blogs, but this one is different. There are natural mathematical reasons why sin/cos are defined with periods of 2\*PI. It wasn't that a bunch of people sat around and said, "How can we define these functions so that we can confuse everyone." If you redefine them differently, then much of the rest of mathematics dealing with these functions changes, including the simple fact that the derivative of the sine function is cosine function.

If you want a different period, it is certainly reasonable to add new functions to the MATH API, but just don't use them to replace the standard trig functions that have stood the test of time and that everyone has learned in school for many, many years (before you were born).

Posted by John Moore on August 01, 2005 at 08:59 PM PDT #

I am also surprised. This is not a question of geting a simpler "clean" period, but of geting the math wrong or right. The trigonometric functions like sinus or cosinus are defined(!) via moving a point on a circular path. E.g. sinus is defined as the relation of the radius to the vertical position. And if we talk about circles, we have to talk about pi (ok, one can make a law and define pi as 4, but that doesn't change nature). If one takes a circle with a radius of 1, then the length of the circumfence is 2\*pi. Period. That's not a "standard practice", that's nature! If you move a point on the circumfence, then the path repeats itself after you traveled for 2\*pi on the circumfence. Voila, here is your period: 2\*pi.

Posted by Carl on August 02, 2005 at 05:08 AM PDT #

A simple reason could be that one normally uses power series to evaluate sin/cos which work with radians, not degrees, so it's simple to have the argument be in radians as well.

Posted by Ranjit Mathew on August 04, 2005 at 03:38 PM PDT #

... bla, bla. Irrelevant ot talk about; do it.

Posted by Marcel Lanz on August 08, 2005 at 03:47 PM PDT #

I agree. 8087 designers were not very smart implementing things using radians. They should have used, say, binadians (define: 2\*\*X binadians = 2\*PI radians). Then shifting to [-PI/4,PI/4] would be a piece of cake and things should be faster and more accurate.

Anyway the problem is making computer maths look like real maths. Accuracy is important, but correctness is much more important in computer maths. After all you want to be sure that that huge set of Java (Fortran/C/C++) files are really solving your equations.

That's what we need in Fortress. And, yes, Fortress should use binadians internally, but should also let us use radians in our source code.

Posted by Antonio on August 10, 2005 at 06:26 PM PDT #

<em>The established fact that Pi is transcendental has not discouraged self-styled thinkers from believing otherwise.

Thus, it so happened, in 1896, that a physician of Indiana in his Solitude had given much thought to the age-old problem of quadrature of the circle. One of his thoughts was that this task might be simplified if one could only find a more propitious value for Pi, such as 3.2.

The good doctor wanted to make his great invention available to all schoolchildren, real estate agents, bureaucrats, and their likes, in Indiana and in the Great World outside – for a consideration, of course.

With visions in his mind of great tsunamis of dollars rolling in, he let it be known – being a good patriot – that he intended not to levy any fees on the use of his Pi in his home state, reserving for himself only a small cut of monies accruing from abroad.

Moving in the very best circles in Indiana, Doc Pi managed to square, if not actually a geometric circle, at least some exalted personage to launch a state of Indiana bill laying down that Pi be henceforth equal to 3.2, exactly.

The bill was carried unanimously by a 67 to 0 vote in the House of Representatives, and thus was on its way to becoming law – to wit, a law of Indiana, not a law of nature.

By a fortunate circumstance, a Purdue University professor of mathematics happened to be visiting the statehouse to lobby for an appropriation for his alma mater when the Senate was about to debate the proposed mathematic lagislation.

During a lull in the debate he succeeded in convincing some of the senators of the horrendous absurdity of the bill – they might just as well pass a law that the Earth is flat (at least in Indiana) – and the debate of the bill was deferred „until a later date“.

</em> -- from „Mathematics: From the Birth of Numbers“ by Jan Gullberg

Posted by eigo on August 14, 2005 at 02:19 AM PDT #

If people want a fast but less accurate trig function they can have it. Use a table of values, this is what many embedded applications do. IE:
```package fasttrig;

import static fasttrig.Time.\*;
import static java.lang.Math.\*;

public class Main {
private static final int nLoops = 10000000;
private static final int sinScale = 100;
private static final int[] sinTable = new int[ sinScale ];
static {
for ( int i = 0; i < sinScale; i++ ) {
sinTable[ i ] = (int)(sin( i \* PI / sinScale ) \* sinScale);
}
}
public static final Timable accurate = new Timable() {
public double time() {
double sum = 0;
for ( int i = 0; i < nLoops; i++ ) {
sum += sin( i \* PI / nLoops );
}
return sum;
}
public String toString() {
return "Math.sin";
}
};
public static final Timable fast = new Timable() {
public double time() {
double sum = 0;
for ( int i = 0; i < nLoops; i++ ) {
final int index = i \* sinScale / nLoops;
final int sinApprox = sinTable[ index ];
sum += (double)sinApprox / sinScale;
}
return sum;
}
public String toString() {
return "Table";
}
};
public static void main( final String[] notUsed ) {
time( accurate );
time( fast );
}
}
```
The output is:
```Test Math.sin, run 0, time taken 2504 ms, result 6366197.723675204
Test Math.sin, run 1, time taken 2493 ms, result 6366197.723675204
Test Table, run 0, time taken 301 ms, result 6314000.000286256
Test Table, run 1, time taken 290 ms, result 6314000.000286256
```
The fast version runs about ten times quicker on my machine (but is 14 places less accurate). I haven't shown the source for <code>Time</code> and <code>Timable</code>, to keep the code short, but you can guess them :) Again taking the lead from embedded applications, if it is OK for trig to be 5 digits then the rest can be 5 digits. Therefore recode the application in fixed point (scalled int) and it will be much faster.

Posted by Howard Lovatt on August 15, 2005 at 12:59 PM PDT #

I had a math professor once who said that the commonly used number system should be in base pi. Kind of an interesting thought especially given that physically there is really no such thing as a straight line.

Posted by John Harby on August 18, 2005 at 12:10 AM PDT #

1

Posted by 1 on August 20, 2005 at 04:07 AM PDT #

An interesting case.

For the purposes of math, sin/cos really \*need\* to have a 2pi period. The simplest way to see this is that (IIRC):

e\^(i theta) = cos theta + i sin theta
That little relation neatly sums up the relationship between i, e, and pi. It's right at the heart of what complex numbers are, and how they work; if cos and sin have any period other than 2pi, calculus (or at least complex analysis) becomes utterly hideous. It's really not fair to say that the motivation for having sin and cos in radians is merely "historical;" "mathematically natural" would be better.

But in software, what's mathematically natural isn't always what's most useful; we usually use sin and cos for doing polar coordinate sorts of things, and the period is arbitrary.

It might make sense for math libraries to define cos1() / sin1(), whose periods are both 1 (e.g. cos1(x) == cos(x \* 2pi)). If it's really a performance problem, I wonder why they don't already?

Posted by Paul Cantrell on August 22, 2005 at 03:52 PM PDT #

dg

Posted by guest on August 29, 2005 at 05:55 AM PDT #

Is there any works being done to actually pass Objects by Reference ? The current implementation is not a true representation and implementation of passing objects by reference.

Posted by Harjit on September 01, 2005 at 01:05 AM PDT #

James, I think your wisdom is infinate.

But I think I might be dividing by zero.

Get it? wink, wink.

mary

Posted by mary on September 07, 2005 at 07:14 AM PDT #

slashdot has an interesting pointer to Dr. Wildberger who has eliminated the need for scones and cosines altogether. At least in Trig. http://web.maths.unsw.edu.au.nyud.net:8090/~norman/book.htm

Posted by Joel Berman on September 17, 2005 at 01:50 AM PDT #

(Well, Joel was faster on this one). The important thing about Dr. Wildberger theory is that is more accurate than trigonometry.

Posted by Antonio on September 17, 2005 at 02:54 AM PDT #

I believe that Mr Gosling is making an interesting point, but everyone is missing it.

It's not that he doesn't understand what radians are or their importance to mathemetics. He's saying that there are a significant number of programs that naturally work with non-radian angular measurements (degrees, grads, revolutions, etc), and only convert to radians in order to access Java's trig functions.

For those programs, argument reduction into the range required by Java (i.e. [-90,90] degrees) can be achieved with simple integer computations BEFORE they apply the appropriate conversion factor (e.g. pi/180) and call the trig function.

Applying the conversion factor first, makes the argument reduction (WRT a transcendental modulus) extremely difficult. So much so that applications skip that step, forcing Java's library functions to deal with it.

If Java were to provide alternative trig functions (e.g. cos_degrees(), tan_degrees(), etc) which performed fast argument reduction MOD 360, then programmers could call the new trig functions for speed, and the current trig function for accuracy.

Furthermore, the fast-vs-accurate choice is not mutually exclusive. Applications which naturally use non-radian units will call the degree-based functions and get both.

Posted by Glynne Casteel on September 17, 2005 at 05:08 AM PDT #

good work.pls send some more java programs for my studies or give some links for java programs. THANK YOU

Posted by thiyagu on September 20, 2005 at 01:46 AM PDT #

Why can't Java just do what the Solaris C Math library does and define a new function sinpi(x) whose value is defined to be sin(pi \* x/180) (http://developers.sun.com/prodtech/cc/documentation/ss10_docs/mr/man3m/cosd.3m.html)

Posted by George Colpitts on October 08, 2005 at 08:59 AM PDT #

Preceding entry should be: Why can't Java just do what the Solaris C Math library does and define a new function sinpi(x) whose value is defined to be sin(pi\*x) thus sinpi(1) == 0.0, cospi(1) == -1.0 etc. this is basically James suggestion that the trig function have a nice period like 1 turn except here the period is two half turns. I guess the guys who implemented the sunpi functions for Sun are retired or at least not workig on Java at Sun For details on sinpi etc. see http://developers.sun.com/prodtech/cc/documentation/ss10_docs/mr/man3m/cosd.3m.html: sinpi(x), cospi(x), and tanpi(x) avoid range-reduction issues because their definition sinpi(x):= sin(n\*x) permits range reduction that is fast and exact for all x. The corresponding inverse functions compute asinpi(x):= asin(x)/n. Similarly atan2pi(y,x):= atan2(y,x)/n.

Posted by George Colpitts on October 03, 2006 at 06:25 AM PDT #

Posted by sasasas on July 22, 2009 at 03:41 PM PDT #

Comments are closed for this entry.

jag

##### Archives
Sun Mon Tue Wed Thu Fri Sat « May 2016 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Today