i want to write a function that rewrite a float to continued fraction - error-handling

i am trying to make a recursive function, that can rewrite a float to an continued fraction. I am getting an error messange that i dont understand
it seems like it can't storage certain numbers binary and how do i compare then. Thats my current theory.
condition 'cfa_reg != -1' not met
let rec float2cfrac (x : float) : int list =
if x - floor x = 0.0 then
[int x]
else
[int x] # float2cfrac (1.0/(x - floor x))
printfn "%A" (float2cfrac 3.245)// list

When I run your code. I get a stack overflow.
That means that your condition x - floor x = 0.0 is never met.
Equality with floating point numbers is a tricky thing as there is always a small precision error involved in all calculations. Never use equality, instead calculate until the difference is less than an acceptable error:
abs(x - floor x) < 0.0000000001

Related

How do you calculate modulo operation with real numbers in system verilog?

For example:
real a = 10.2917541278;
real modout;
assign modout = (a % 3.142);
Currently, this is not supported, I get an error saying numbers need to be integers.
I don't want this code to be synthesized. This is only in the testbench.
The concept of a modulus in real number math is a bit weird since the result of the division of two real numbers should be a real number (ignoring zero). If however, you want something like fmod in C/C++, you can implement it like so:
real x, d, r;
assign r = x - d * $floor(x / d); // Implements fmod(x, d) or "x % d" for real x, d

Calculating distance between 2 points fails when points are the same

I am running following SQL query in my JAVA Spring server. This query works perfect for almost all coordinates except for one specific pair c = <23.065079, 72.511478> (= to_lat, to_long):
SELECT *
FROM karpool.ride
WHERE Acos(Sin(Radians(23.065079)) * Sin(Radians(to_lat)) +
Cos(Radians(23.065079)) * Cos(Radians(to_lat)) *
Cos(Radians(to_lon) - Radians(72.511478))) * 6371 <= 10;
My database has many locations within 10 km distance to c. With the above query, I get all those locations' distances, except for the one which exactly matches with c. The distance returned should be 0 in that case, but the query fails.
Is this an SQL issue or is there something wrong with the formula?
This is most probably due to floating point accuracy problems.
First of all, the used formula is the Great circle distance formula:
Let φ1,λ1 and φ1,λ2 be the geographical latitude and longitude of two points 1 and 2, and Δφ,Δλ their absolute differences; then Δσ, the central angle between them, is given by the spherical law of cosines:
Δσ = arccos ( sin φ1 ∙ sin φ2 + cos φ1 ∙ cos φ2 ∙ cos (Δλ) ).
The distance d, i.e. the arc length, for a sphere of radius r and Δσ given in radians
d = r Δσ.
Now if the two points are the same, then Δλ = 0, and thus cos(Δλ) = cos(0) = 1, and the first formula reduces to:
Δσ = arccos (sin φ ∙ sin φ + cos φ ∙ cos φ).
The argument to arccos has become the Pythagorean trigonometric identity, and thus equals 1.
So the above reduces to:
Δσ = arccos (1).
The problem
The domain of the arccosine is: −1 ≤ x ≤ 1, so with the value 1 we are at the boundary of the domain.
As the value of 1 was the result of several floating point operations (sines, cosines, multiplications), it could occur that the value is not exactly 1, but something like 1.0000000000004. That poses a problem, for that value is out of range for calculating the arccosine. Database engines respond differently to this situation:
SQL Server will raise an exception:
An invalid floating point operation occurred.
MySql will just evaluate the expression as null.
The solution
Somehow the argument passed to the arccosine should be made to stay in the range −1 ≤ x ≤ 1. One way of doing this, is to round the argument to a number of decimals that is large enough to keep some precision, but small enough to round away any excess outside this range caused by floating point operations.
Most database engines have a round function to which a second argument can be provided to specify the number of digits to keep, and so the SQL would look like this (keeping 6 decimals):
SELECT *
FROM karpool.ride
WHERE Acos(Round(
Sin(Radians(23.065079)) * Sin(Radians(to_lat)) +
Cos(Radians(23.065079)) * Cos(Radians(to_lat)) *
Cos(Radians(to_lon) - Radians(72.511478)),
6
)) * 6371 <= 10;
Alternatively, you could use the functions greatest and least, which some database engines provide, to turn any excess value to 1 (or -1):
SELECT *
FROM karpool.ride
WHERE Acos(Greatest(Least(
Sin(Radians(23.065079)) * Sin(Radians(to_lat)) +
Cos(Radians(23.065079)) * Cos(Radians(to_lat)) *
Cos(Radians(to_lon) - Radians(72.511478)),
1), -1)
) * 6371 <= 10;
Note that SQL Server does not provide greatest/least functions. A question to overcome this has several answers.

Why do some C math expressions require constants to be explicitly marked as floats?

So I just found this bug in my code and I am wondering what rules I'm not understanding.
I have a float variable logDiff, that currently contains a very small number. I want to see if it's bigger than a constant expression (80% of a 12th). I read years ago in Code Complete to just leave calculated constants in their simplest form for readability, and the compiler (XCode 4.6.3) will inline them anyway. So I have,
if ( logDiff > 1/12 * .8 ) {
I'm assuming the .8 and the fraction all evaluates to the correct number. Looks legit:
(lldb) expr (float) 1/12 * .8
(double) $1 = 0.0666666686534882
(lldb) expr logDiff
(float) $2 = 0.000328541
But it always wrongly evaluates to true. Even when I mess with enclosing parens and stuff.
(lldb) expr logDiff > 1/12 * .8
(bool) $4 = true
(lldb) expr logDiff > (1/12 * .8)
(bool) $5 = true
(lldb) expr logDiff > (float)(1/12 * .8)
(bool) $6 = true
I found I have to explicitly spell at least one of them as floats to get the correct result,
(lldb) expr logDiff > (1.f/12.f * .8f)
(bool) $7 = false
(lldb) expr logDiff > (1/12.f * .8)
(bool) $8 = false
(lldb) expr logDiff > (1./12 * .8f)
(bool) $11 = false
(lldb) expr logDiff > (1./12 * .8)
(bool) $12 = false
but I recently read a popular style guide explicitly eschew these fancier numeric literals, apparently according to my assumption that the compiler would be smarter than me and Do What I Mean.
Should I always spell my numeric constants like 1.f if they might need to be a float? Sounds superstitious. Help me understand why and when it's necessary?
The expression 1/12 is an integer division. That means that the result will be truncated as zero.
When you do (float) 1/12 you cast the one as a float, and the whole expression becomes a floating point expression.
In C int/int gives an int. If you don't explicitly tell the compiler to convert at least one to a float, it will do the division and round down to the nearest int (in this case 0).
I note that the linked style guide actually says Avoid making numbers a specific type unless necessary. In this case it is needed as what you want is for the compiler to do some type conversions
An expression such as 1 / 4 is treated as integer division and hence has no decimal precision. In this specific case, the result will be 0. You can think of this as int / int implies int.
Should I always spell my numeric constants like 1.f if they might need to be a float? Sounds superstitious. Help me understand why and when it's necessary?
It's not superstitious, you are telling the compiler that these are type literals (floats as an example) and the compiler will treat all operations on them as such.
Moreover, you could cast an expression. Consider the following:
float result = ( float ) 1 / 4;
... I am casting 1 to be a float and hence the result of float / int will be float. See datatype operation precedence (or promotion).
That is simple. Per default, a numeric value is interpredted as an int.
There are math expresssions where that does not matter too much. But in case of divisions it can drive you crazy. (int) 1 / (int) 12 is not (float) 0.08333 but (int) 0.
1/12.0 would evaluate to (float) 0.83333.
Side note: When you go for float where you used int before there is one more trap waiting for you. That is when ever you compare values for equality.
float f = 12/12.0f;
if (f = 1) ... // this may not work out. Never expect a float to be of a specific value. They can vary slightly.
Better is:
if (abs(f - 1) < 0.0001) ... // this way yoru comparison is fuzzy enough for the variances that float values may come with.

Is there an iterative way to calculate radii along a scanline?

I am processing a series of points which all have the same Y value, but different X values. I go through the points by incrementing X by one. For example, I might have Y = 50 and X is the integers from -30 to 30. Part of my algorithm involves finding the distance to the origin from each point and then doing further processing.
After profiling, I've found that the sqrt call in the distance calculation is taking a significant amount of my time. Is there an iterative way to calculate the distance?
In other words:
I want to efficiently calculate: r[n] = sqrt(x[n]*x[n] + y*y)). I can save information from the previous iteration. Each iteration changes by incrementing x, so x[n] = x[n-1] + 1. I can not use sqrt or trig functions because they are too slow except at the beginning of each scanline.
I can use approximations as long as they are good enough (less than 0.l% error) and the errors introduced are smooth (I can't bin to a pre-calculated table of approximations).
Additional information:
x and y are always integers between -150 and 150
I'm going to try a couple ideas out tomorrow and mark the best answer based on which is fastest.
Results
I did some timings
Distance formula: 16 ms / iteration
Pete's interperlating solution: 8 ms / iteration
wrang-wrang pre-calculation solution: 8ms / iteration
I was hoping the test would decide between the two, because I like both answers. I'm going to go with Pete's because it uses less memory.
Just to get a feel for it, for your range y = 50, x = 0 gives r = 50 and y = 50, x = +/- 30 gives r ~= 58.3. You want an approximation good for +/- 0.1%, or +/- 0.05 absolute. That's a lot lower accuracy than most library sqrts do.
Two approximate approaches - you calculate r based on interpolating from the previous value, or use a few terms of a suitable series.
Interpolating from previous r
r = ( x2 + y2 ) 1/2
dr/dx = 1/2 . 2x . ( x2 + y2 ) -1/2 = x/r
double r = 50;
for ( int x = 0; x <= 30; ++x ) {
double r_true = Math.sqrt ( 50*50 + x*x );
System.out.printf ( "x: %d r_true: %f r_approx: %f error: %f%%\n", x, r, r_true, 100 * Math.abs ( r_true - r ) / r );
r = r + ( x + 0.5 ) / r;
}
Gives:
x: 0 r_true: 50.000000 r_approx: 50.000000 error: 0.000000%
x: 1 r_true: 50.010000 r_approx: 50.009999 error: 0.000002%
....
x: 29 r_true: 57.825065 r_approx: 57.801384 error: 0.040953%
x: 30 r_true: 58.335225 r_approx: 58.309519 error: 0.044065%
which seems to meet the requirement of 0.1% error, so I didn't bother coding the next one, as it would require quite a bit more calculation steps.
Truncated Series
The taylor series for sqrt ( 1 + x ) for x near zero is
sqrt ( 1 + x ) = 1 + 1/2 x - 1/8 x2 ... + ( - 1 / 2 )n+1 xn
Using r = y sqrt ( 1 + (x/y)2 ) then you're looking for a term t = ( - 1 / 2 )n+1 0.36n with magnitude less that a 0.001, log ( 0.002 ) > n log ( 0.18 ) or n > 3.6, so taking terms to x^4 should be Ok.
Y=10000
Y2=Y*Y
for x=0..Y2 do
D[x]=sqrt(Y2+x*x)
norm(x,y)=
if (y==0) x
else if (x>y) norm(y,x)
else {
s=Y/y
D[round(x*s)]/s
}
If your coordinates are smooth, then the idea can be extended with linear interpolation. For more precision, increase Y.
The idea is that s*(x,y) is on the line y=Y, which you've precomputed distances for. Get the distance, then divide it by s.
I assume you really do need the distance and not its square.
You may also be able to find a general sqrt implementation that sacrifices some accuracy for speed, but I have a hard time imagining that beating what the FPU can do.
By linear interpolation, I mean to change D[round(x)] to:
f=floor(x)
a=x-f
D[f]*(1-a)+D[f+1]*a
This doesn't really answer your question, but may help...
The first questions I would ask would be:
"do I need the sqrt at all?".
"If not, how can I reduce the number of sqrts?"
then yours: "Can I replace the remaining sqrts with a clever calculation?"
So I'd start with:
Do you need the exact radius, or would radius-squared be acceptable? There are fast approximatiosn to sqrt, but probably not accurate enough for your spec.
Can you process the image using mirrored quadrants or eighths? By processing all pixels at the same radius value in a batch, you can reduce the number of calculations by 8x.
Can you precalculate the radius values? You only need a table that is a quarter (or possibly an eighth) of the size of the image you are processing, and the table would only need to be precalculated once and then re-used for many runs of the algorithm.
So clever maths may not be the fastest solution.
Well there's always trying optimize your sqrt, the fastest one I've seen is the old carmack quake 3 sqrt:
http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
That said, since sqrt is non-linear, you're not going to be able to do simple linear interpolation along your line to get your result. The best idea is to use a table lookup since that will give you blazing fast access to the data. And, since you appear to be iterating by whole integers, a table lookup should be exceedingly accurate.
Well, you can mirror around x=0 to start with (you need only compute n>=0, and the dupe those results to corresponding n<0). After that, I'd take a look at using the derivative on sqrt(a^2+b^2) (or the corresponding sin) to take advantage of the constant dx.
If that's not accurate enough, may I point out that this is a pretty good job for SIMD, which will provide you with a reciprocal square root op on both SSE and VMX (and shader model 2).
This is sort of related to a HAKMEM item:
ITEM 149 (Minsky): CIRCLE ALGORITHM
Here is an elegant way to draw almost
circles on a point-plotting display:
NEW X = OLD X - epsilon * OLD Y
NEW Y = OLD Y + epsilon * NEW(!) X
This makes a very round ellipse
centered at the origin with its size
determined by the initial point.
epsilon determines the angular
velocity of the circulating point, and
slightly affects the eccentricity. If
epsilon is a power of 2, then we don't
even need multiplication, let alone
square roots, sines, and cosines! The
"circle" will be perfectly stable
because the points soon become
periodic.
The circle algorithm was invented by
mistake when I tried to save one
register in a display hack! Ben Gurley
had an amazing display hack using only
about six or seven instructions, and
it was a great wonder. But it was
basically line-oriented. It occurred
to me that it would be exciting to
have curves, and I was trying to get a
curve display hack with minimal
instructions.

Weird Objective-C Mod Behavior for Negative Numbers

So I thought that negative numbers, when mod'ed should be put into positive space... I cant get this to happen in objective-c
I expect this:
-1 % 3 = 2
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
But get this
-1 % 3 = -1
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
Why is this and is there a workaround?
result = n % 3;
if( result < 0 ) result += 3;
Don't perform extra mod operations as suggested in the other answers. They are very expensive and unnecessary.
In C and Objective-C, the division and modulus operators perform truncation towards zero. a / b is floor(a / b) if a / b > 0, otherwise it is ceiling(a / b) if a / b < 0. It is always the case that a == (a / b) * b + (a % b), unless of course b is 0. As a consequence, positive % positive == positive, positive % negative == positive, negative % positive == negative, and negative % negative == negative (you can work out the logic for all 4 cases, although it's a little tricky).
If n has a limited range, then you can get the result you want simply by adding a known constant multiple of 3 that is greater that the absolute value of the minimum.
For example, if n is limited to -1000..2000, then you can use the expression:
result = (n+1002) % 3;
Make sure the maximum plus your constant will not overflow when summed.
We have a problem of language:
math-er-says: i take this number plus that number mod other-number
code-er-hears: I add two numbers and then devide the result by other-number
code-er-says: what about negative numbers?
math-er-says: WHAT? fields mod other-number don't have a concept of negative numbers?
code-er-says: field what? ...
the math person in this conversations is talking about doing math in a circular number line. If you subtract off the bottom you wrap around to the top.
the code person is talking about an operator that calculates remainder.
In this case you want the mathematician's mod operator and have the remainder function at your disposal. you can convert the remainder operator into the mathematician's mod operator by checking to see if you fell of the bottom each time you do subtraction.
If this will be the behavior, and you know that it will be, then for m % n = r, just use r = n + r. If you're unsure of what will happen here, use then r = r % n.
Edit: To sum up, use r = ( n + ( m % n ) ) % n
I would have expected a positive number, as well, but I found this, from ISO/IEC 14882:2003 : Programming languages -- C++, 5.6.4 (found in the Wikipedia article on the modulus operation):
The binary % operator yields the remainder from the division of the first expression by the second. .... If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined
JavaScript does this, too. I've been caught by it a couple times. Think of it as a reflection around zero rather than a continuation.
Why: because that is the way the mod operator is specified in the C-standard (Remember that Objective-C is an extension of C). It confuses most people I know (like me) because it is surprising and you have to remember it.
As to a workaround: I would use uncleo's.
UncleO's answer is probably more robust, but if you want to do it on a single line, and you're certain the negative value will not be more negative than a single iteration of the mod (for example if you're only ever subtracting at most the mod value at any time) you can simplify it to a single expression:
int result = (n + 3) % 3;
Since you're doing the mod anyway, adding 3 to the initial value has no effect unless n is negative (but not less than -3) in which case it causes result to be the expected positive modulus.
There are two choices for the remainder, and the sign depends on the language. ANSI C chooses the sign of the dividend. I would suspect this is why you see Objective-C doing so also. See the wikipedia entry as well.
Not only java script, almost all the languages shows the wrong answer'
what coneybeare said is correct, when we have mode'd we have to get remainder
Remainder is nothing but which remains after division and it should be a positive integer....
If you check the number line you can understand that
I also face the same issue in VB and and it made me to forcefully add extra check like
if the result is a negative we have to add the divisor to the result
Instead of a%b
Use: a-b*floor((float)a/(float)b)
You're expecting remainder and are using modulo. In math they are the same thing, in C they are different. GNU-C has Rem() and Mod(), objective-c only has mod() so you will have to use the code above to simulate rem function (which is the same as mod in the math world, but not in the programming world [for most languages at least])
Also note you could define an easy to use macro for this.
#define rem(a,b) ((int)(a-b*floor((float)a/(float)b)))
Then you could just use rem(-1,3) in your code and it should work fine.