I am trying to create a vector with random dimensions, but with a magnitude of 1. This is what I've come up with (removed the rand() function and replaced it with a number common to both pieces of code.):
float x = sqrt((4566%100)/100.f);
float y = sqrt(1.f-x);
printf("%f, %f\n", x, y);
printf("%f\n", (x*x)+(y*y));
The output is this:
0.812404, 0.433124
0.847596
but when I remove the inverse of the pythagorean theorum (with the code looking a little something like this):
float x = (4566%100)/100.f;
float y = 1.f-x;
printf("%f, %f\n", x, y);
printf("%f\n", x+y);
the output looks like this:
0.660000, 0.340000
1.000000
Based on the assumption that I'm not insane, the output of the last line of the first piece of code should be 1, and the vector being printed above should be something completely different. I can only assume that the thing that has gone wrong is in the sqrt function. If it is, could someone help me fix it and if it isn't, could someone help me identify my error?
If, according to the Pythagorean theorem, sqrt(x * x + y * y) = 1, then y is not equal to sqrt(1.f-x). It should be sqrt(1.f-x*x):
sqrt(x * x + y * y) = 1
(square both sides) => x * x + y * y = 1
(subtract x * x from both sides) => y * y = 1 - x * x
(calculate the square root of both sides) => y = sqrt(1 - x * x)
Given the computation for x, this computation of y is incorrect:
float y = sqrt(1.f-x);
You need to subtract the square of x:
float y = sqrt(1.f-x*x);
Since x is between 0 and 1, x2 < x, and that will yield a larger (and correct, modulo FP error) value of y.
I want to work out if I have an object in space, and I know how fast it will travel in a second and at what angle it is going, where it will end up on the x y and z.
`I have already tried using the same equation for x, and y, but neither quite come out right, and I think it is a logic error.
Idealy, I'd want to know: 1, how to calculate it. I'd expect a result of: {x, y, z} where x y and z are finishing coordinates.
Additional code:
dx=distance traveled on x
dy=distance traveled on y
dz=distance traveled on z:
xb = dx * sin(angle1);
y= dy * cos(angle1);
z= dz * cos(angle2);
Generally, I know that I can get a random element of an array in the following way:
var myArray = [x, y, z]
let myArrayLength = UInt32(myArray.count)
let myArrayIndex = Int(arc4random_uniform(myArrayLength))
let randomElement = myArray[myArrayIndex]
But how can I make the possibility of y being the random element twice the possibility of x and z being the random element thrice the possibility of y?
UPDATE
NB: Where x, y and z are CGPoints
An easy way is to rewrite your array like this: [x,x,y,z]. Then, the probability of getting x becomes 0.5, the probability of y becomes 0.25 and the probability of z becomes 0.25. Just repeat the symbols with high probability as much as you want, for example [x, y, y, z, z, z, z] is good for what you asked for.
I'm trying to produce a colored graph using the below code
x = range(0,170)
y = range(0,60)
X,Y = meshgrid(x, y) # grid of point
Z = ATFS.ATFS(state, T, dt, Y, tm, td, sigma, D, X, f, A, measurement)
Where ATFS uses X in a matrix. This produces the error
arr = N.array(data, dtype=dtype, copy=copy)
ValueError: setting an array element with a sequence.
I know if I use Z = X*Y it works and it doesn't matter that they are a sequence so what wrong here?
I would like to compute the norm (length) of three- and four-dimensional vectors. I'm using double-precision floating point numbers and want to be careful to avoid unnecessary overflow or underflow.
The C math library provides hypot(x,y) for computing the norm of two-dimensional vectors, being careful to avoid underflow/overflow in intermediate calculations.
My question: Is it safe to use hypot(x, hypot(y, z)) and hypot(hypot(w, x), hypot(y, z)) to compute the lengths of three- and four-dimensional vectors, respectively?
It's safe, but it's wasteful: you only need to compute sqrt() once, but when you cascade hypot(), you will call sqrt() for every call to hypot(). Ordinarily I might not be concerned about the performance, but this may also degrade the precision of the result. You could write your own:
double hypot3(double x, double y, double z) {
return sqrt(x*x + y*y + z*z);
}
etc. This will be faster and more accurate. I don't think anyone would be confused when they see hypot3() in your code.
The standard library hypot() may have tricks to avoid overflow, but you may not be concerned about it. Ordinarily, hypot() is more accurate than sqrt(x*x + y*y). See e_hypot.c in the GLibC source code.
It safe (almost) to use hypot(x, hypot(y, z)) and hypot(hypot(w, x), hypot(y, z)) to compute the lengths of three- and four-dimensional vectors.
C does not strongly specify that hypot() must work for a double x, y that have a finite double answer. It has weasel words of "without undue overflow or underflow".
Yet given that hypot(x, y) works, a reasonable hypot() implementation will perform hypot(hypot(w, x), hypot(y, z)) as needed. There is only 1 increment (at the low end) /decrement (at the high end) of binary exponent range lost when with 4-D vs. 2-D.
Concerning speed, precision, and range, code profile against sqrtl((long double) w*w + (long double) x*x + (long double) y*y + (long double) z*z) as an alternative, but that seems only needed with select coding goals.
I've done some experiments with this sort of thing. In particular I looked at a plain implementation, an implementation using hypots and (a C translation of the reference version of) the BLAS function DNRM2.
I found that as regards over and underflow, the BLAS and hypot implementations were the same (in my tests) and far superior to the plain implementation. As regards time, for high (hundreds) dimensioned vectors, the BLAS was about 6 times slower than the plain, while the hypot was 3 times slower than BLAS. The time differences were a bit smaller for smaller dimensions.
Should code not be able to use hypot() nor wider precision types, a slow method examines the exponents using frexp() and scales the argumnets #greggo.
#include <math.h>
double nibot_norm(double w, double x, double y, double z) {
// Sort the values by some means
if (fabs(x) < fabs(w)) return nibot_norm(x, w, y, z);
if (fabs(y) < fabs(x)) return nibot_norm(w, y, x, z);
if (fabs(z) < fabs(y)) return nibot_norm(w, x, z, y);
if (z == 0.0) return 0.0; // all zero case
// Scale z to exponent half-way 1.0 to MAX_DOUBLE/4
// and w,x,y the same amount
int maxi;
frexp(DBL_MAX, &maxi);
int zi;
frexp(z, &zi);
int pow2scale = (maxi / 2 - 2) - zi;
// NO precision loss expected so far.
// except w,x,y may become 0.0 if _far_ less than z
w = ldexp(w, pow2scale);
x = ldexp(x, pow2scale);
y = ldexp(y, pow2scale);
z = ldexp(z, pow2scale);
// All finite values in range of squaring except for values
// greatly insignificant to z (e.g. |z| > |x|*1e300)
double norm = sqrt(((w * w + x * x) + y * y) + z * z);
// Restore scale
return ldexp(norm, -pow2scale);
}
Test Code
#include <float.h>
#include <stdio.h>
#ifndef DBL_TRUE_MIN
#define DBL_TRUE_MIN DBL_MIN*DBL_EPSILON
#endif
void nibot_norm_test(double w, double x, double y, double z, double expect) {
static int dig = DBL_DECIMAL_DIG - 1;
printf(" w:%.*e x:%.*e y:%.*e z:%.*e\n", dig, w, dig, x, dig, y, dig, z);
double norm = nibot_norm(w, x, y, z);
printf("expect:%.*e\n", dig, expect);
printf("actual:%.*e\n", dig, norm);
if (expect != norm) puts("Different");
}
int main(void) {
nibot_norm_test(0, 0, 0, 0, 0);
nibot_norm_test(10 / 7., 4 / 7., 2 / 7., 1 / 7., 11 / 7.);
nibot_norm_test(DBL_MAX, 0, 0, 0, DBL_MAX);
nibot_norm_test(DBL_MAX / 2, DBL_MAX / 2, DBL_MAX / 2, DBL_MAX / 2, DBL_MAX);
nibot_norm_test(DBL_TRUE_MIN, 0, 0, 0, DBL_TRUE_MIN);
nibot_norm_test(DBL_TRUE_MIN, DBL_TRUE_MIN, DBL_TRUE_MIN,
DBL_TRUE_MIN, DBL_TRUE_MIN * 2);
return 0;
}
Results
w:0.00000000000000000e+00 x:0.00000000000000000e+00 y:0.00000000000000000e+00 z:0.00000000000000000e+00
expect:0.00000000000000000e+00
actual:0.00000000000000000e+00
w:1.42857142857142860e+00 x:5.71428571428571397e-01 y:2.85714285714285698e-01 z:1.42857142857142849e-01
expect:1.57142857142857140e+00
actual:1.57142857142857140e+00
w:1.79769313486231571e+308 x:0.00000000000000000e+00 y:0.00000000000000000e+00 z:0.00000000000000000e+00
expect:1.79769313486231571e+308
actual:1.79769313486231571e+308
w:8.98846567431157854e+307 x:8.98846567431157854e+307 y:8.98846567431157854e+307 z:8.98846567431157854e+307
expect:1.79769313486231571e+308
actual:1.79769313486231571e+308
w:4.94065645841246544e-324 x:0.00000000000000000e+00 y:0.00000000000000000e+00 z:0.00000000000000000e+00
expect:4.94065645841246544e-324
actual:4.94065645841246544e-324
w:4.94065645841246544e-324 x:4.94065645841246544e-324 y:4.94065645841246544e-324 z:4.94065645841246544e-324
expect:9.88131291682493088e-324
actual:9.88131291682493088e-324