sqrtf(6)*sqrtf(6) != 6 in xcode - objective-c

I'm trying to create a software that shows the angle between two vectors and it's not working when then are equal to (1,1,2), hence the modulus of this vector is sqrtf(6) which is rouding to 2.449490 and it should be 2.44948974278318.
Is there a way to increase precision of this operation?
In the next steps of my software I make this operation:
float angle = acos(dot/(modulus1*modulus2));
If modulus1 == modulus 2, then modulus1*modulus2 = dot, but it's not happening with some values.
I hope I made myself clear.
Thanks in advance,
Gruber

You can use double if you want greater precision. However, note that the == operation on floating point numbers never work the way they do with integral types. Use an epsilon to adjust for minor differences.

Related

arccos((sin(x)^2)+cos(x)^2) is not 0 for certain angles

I am struggling with a simple calculation problem.
By theory for an arbitrary angle:
If
is
If I implement this in python or Matlab:
import numpy as np
alpha = -89.999961
alpha_rad = np.deg2rad(alpha)
result = np.arccos(np.sin(alpha_rad)**2 + np.cos(alpha_rad)**2)
print('%.16f' % result)
leads to
0.0000000149011612
whereas
alpha = -89.9999601
leads to
0.0000000000000000
It is also practically 0 using -89.999962°, but it is again 1.49011612e-08 for alpha = -89.9999°
Does anybody know the reason for this and which angles will lead to results bigger than 0. I am not an big expert in numerical mathematics, but the spacing of floating numbers is much smaller (2.220446049250313e-16). I want to multiply the result with a large number so it would be great, if the result is 0 in terms of floating numbers spacing.
Any help and explanation is very welcome!
It's the same in Java too and in other programming languages. The fractional part of a floating point number is finite so there are computational errors in resolving certain values. So in some cases you will need to round to get the expected result.
Here is a Java example of the same issue.
double[] angles = { 23.4, 22, 78.3, 92.4
};
for (double a : angles) {
double val = Math.sin(a) * Math.sin(a) + Math.cos(a) * Math.cos(a);
System.out.println(Math.acos(val) + " " + a);
System.out.println("-------------------------------");
}
}
If you search for subjects like dealing with floating point errors you may get some insight into this as well as how to handle it.
solves the problem for arbitrary angles. Cosines is known for numerical problems (e.g. https://www.nayuki.io/page/numerically-stable-law-of-cosines)

gpu optimization when multiplying by powers of 2 in a shader

Do modern GPUs optimize multiplication by powers of 2 by doing a bit shift? For example suppose I do the following in a shader:
float t = 0;
t *= 16;
t *= 17;
Is it possible the first multiplication will run faster than the second?
Floating point multiplication cannot be done by bit shift. Howerver, in theory floating point multiplication by power of 2 constants can be optimized. Floating point value is normally stored in the form of S * M * 2 ^ E, where S is a sign, M is mantissa and E is exponent. Multiplying by a power of 2 constant can be done by adding/substracting to the exponent part of the float, without modifying the other parts. But in practice, I would bet that on GPUs a generic multiply instruction is always used.
I had an interesting observation regarding the power of 2 constants while studying the disassembly output of the PVRShaderEditor (PowerVR GPUs). I have noticed that a certain range of power of 2 constants ([2^(-16), 2^10] in my case), use special notation, e.g. C65, implying that they are predefined. Whereas arbitrary constants, such as 3.0 or 2.3, use shared register notation (e.g. SH12), which implies they are stored as a uniform and probably incur some setup cost. Thus using power of 2 constants may yield some optimizational benefit at least on some hardware.

fmincon : impose vector greater than zero constraint

How do you impose a constraint that all values in a vector you are trying to optimize for are greater than zero, using fmincon()?
According to the documentation, I need some parameters A and b, where A*x ≤ b, but I think if I make A a vector of -1's and b 0, then I will have optimized for the sum of x>0, instead of each value of x greater than 0.
Just in case you need it, here is my code. I am trying to optimize over a vector (x) such that the (componentwise) product of x and a matrix (called multiplierMatrix) makes a matrix for which the sum of the columns is x.
function [sse] = myfun(x) % this is a nested function
bigMatrix = repmat(x,1,120) .* multiplierMatrix;
answer = sum(bigMatrix,1)';
sse = sum((expectedAnswer - answer).^2);
end
xGuess = ones(1:120,1);
[sse xVals] = fmincon(#myfun,xGuess,???);
Let me know if I need to explain my problem better. Thanks for your help in advance!
You can use the lower bound:
xGuess = ones(120,1);
lb = zeros(120,1);
[sse xVals] = fmincon(#myfun,xGuess, [],[],[],[], lb);
note that xVals and sse should probably be swapped (if their name means anything).
The lower bound lb means that elements in your decision variable x will never fall below the corresponding element in lb, which is what you are after here.
The empties ([]) indicate you're not using linear constraints (e.g., A,b, Aeq,beq), only the lower bounds lb.
Some advice: fmincon is a pretty advanced function. You'd better memorize the documentation on it, and play with it for a few hours, using many different example problems.

Why does CLng produce different results?

Here's a little gem directly from my VBE (MS Excel 2007 VBA):
?clng(150*0.85)
127
x = 150*0.85
?clng(x)
128
Can anybody explain this behaviour? IMHO the first expression should yield 128 (.5 rounded to nearest even), or at least should both results be equal.
I think wqw is right, but I'll give the details.
In the statement clng(150 * 0.85), 150 * 0.85 is calculated in extended-precision:
150 = 1.001011 x 2^7
0.85 in double precision =
1.1011001100110011001100110011001100110011001100110011 x 2^-1
Multiply these by hand and you get
1.1111110111111111111111111111111111111111111111111111110001 x 2^6 =
127.4999999999999966693309261245303787291049957275390625
That's 59 bits, which fits comfortably in extended-precision. It's less than 127.5 so rounds down.
In the statement x = 150 * 0.85, that 59 bit value is rounded to 53 bits, giving
1.1111111 x 2^6 = 1111111.1 = 127.5
So it rounds up according to round-half-to-even.
(See my article http://www.exploringbinary.com/when-doubles-dont-behave-like-doubles/ for more information.)
Ahh one of the “fun” things about VBA is the rounding on CInt() etc is what is called bankers rounding. Bankers rounding is where 0.5 values are rounded up or down depending on if the number is an even number so 2.5 rounds to 2, 3.5 to 4 and so on.
More can be found here about rounding
http://www.consultdmw.com/rounding-numbers.htm
This is a bit of a guess, but .85 may not be representable as a floating point number. If it is off by 0.0000000000001 it can still affect rounding in weird ways.
If you use CDec(.85) to force it into decimal mode you don't get that weirdness. This is one of the many reasons why I don't use single/double where accuracy is important.
My theory is VBA/VB6 is using x87 for floating point calculations and this implicitly converts doubles to higher precision if 80 bits for intermediate results. So an assignment to v or explicit cast with CDbl converts intermediate 80-bits value back to 64-bits effectivly rounding it (or truncating it).
Here is some discussion:
Extended (80-bit) double floating point in x87, not SSE2 - we don't miss it?
Both what Kevin and Jonathan have said are true, but Jonathan's answer is more applicable here. If you were dealing with Currency-type numbers instead of floating point, then the Banker's rounding rule would be applied.

formulas in Projectile Motion?

how can i calculate angle to reach particular height?
suppose i want height 320.time is increasing as 0.1.
i am using h = (u sin(angle))^2 / 2g;
where can i put the time?
The inverse of the sin() function is called the arcsine, or sin-1 in mathematical notation. In many programming languages, it's available as asin().
From my answer to your previous question:
Where y is the height you want to reach (320 in this case), and assuming you're starting at y=0:
angle = arctan( 2*y / x )
where x is the distance on the X-AXIS between your starting point and the point where you want to reach that height, which is necessary in order to specify an angle.
If you really want me to, I can derive this one for you, but it follows directly from my answer to your previous question.
Also (since I can't comment answers yet I'm saying this here), you may be having issues getting an angle "less than 1" because you're trying to use degrees instead of radians. Many math libraries work in radians, so convert your angles.