So I have this equation: x % a = b. Values a and b are already known. I want to find the value of x. So, how do I reverse plain modulus? Everything I've found was in the order (a + x) % m = b.
I need to do this for an encryption algorithm. It has a way of knowing what the number is, I just need to separate out the parts of it and this is the only part I haven't reversed.
Assume x, a, and b are integers, as the other commenters have noted, you cannot find a unique value. In fact, there are an infinite number of x values that will work, namely x = b, x = b + a, x = b + 2 * a, ... or:
x = b + a*k, for any integer k.
Of course, for an actual java int (or long) there are only a finite set of x values.
Related
Is there a way to represent a 3D Vector as a definite number? I mean that two vectors with different values can't ever have the same hash value. I'm sure there already is a question about this but I haven't found it unfortunately. Thanks for your help.
EDIT:
I know this algorithm for 2D vectors which is pretty good (I think): (x + y) * (x + y + 1) / 2 + y
The best approach to get a hash for a vector of floats is to convert it to a string of bytes or characters and calculate a hash on it. An example of this is given using numpy and python in the following answer:
Most efficient property to hash for numpy array.
This will work efficiently for large numbers of vectors, but you cannot guarantee that you will not get collisions due to the simple fact of mapping three floats onto an integer. However there are a number of hashing algorithms available in the python hashlib library to choose from, you might need to experiment. An option in C++ is Boost::Hash.
See the pigeon-hole principle - in the same way you can't fit you can't 100 pigeons into 10 holes, you can't uniquely convert 3 values into 1 value (with all values of the same size). There will have to be duplicates.
Now, if you could have a number with 3x as many bits as the vector values, the problem becomes fairly easy:
// convert x, y and z to the range 0-...
x -= minimum possible value
y -= minimum possible value
z -= minimum possible value
mult = maximum possible value + 1
hash = x * mult * mult + y * mult + z
If you're having trouble understanding the above, just take the example of the range of the values being 0-99. We'd multiple x by 100*100 = 10000 and y by 100, so the hash would be a decimal value with (at most) 6 digits with x, y and z all next to each other, guaranteed to not overlap:
x = 12
y = 34
z = 56
hash = 123456
Now this same idea will hold for any maximum value by just changing the base / radix.
If there isn't any overlap in some base, each unique combination of values of x, y and z will result in a unique hash.
This is by far the simplest approach, although it doesn't produce a particularly good hash, so it depends what you want to use it for - there might be a way to uniquely convert this number to another number which will be a good hash.
Responding to this post a little late, and perhaps this isn't what you're looking for, but I figured I would chime in with another answer.
You could use the function you mentioned, (x + y) * (x + y + 1) / 2 + y , and do it recursively, ex. f( f(x,y) , z).
You can also use other pairing functions as well and use the same method (https://en.wikipedia.org/wiki/Pairing_function).
For my problem, I wanted a function that would order vectors based on their location. The order itself didn't matter, only that a close value means a similar vector. What I ended up doing was:
double get_pairing(double x, double y, double z) {
double normalizer = 0.0;
if(x < 0) {
normalizer += (3.0 * MAX_COORD_VAL);
}
if (y < 0) {
normalizer += (6.0 * MAX_COORD_VAL);
}
if (z < 0) {
normalizer += (9.0 * MAX_COORD_VAL);
}
double g = x + y + z - normalizer + (21 * MAX_COORD_VAL);
return g;
}
This orders vectors based on whether they have negative coordinate values and whether they have large coordinate values.
This works assuming you have a max coordinate value.
Just a quick question about the bitwise operator &.
If know that x & y == z and I know the value of y and z is there a way I can calculate the value of x?
If you are told that x is unique, then no, there is no way of doing it for arbitrary values of y. Otherwise, there are 2n different solutions to that equation, where n is the number of zero bits of y.
As an example, let's consider single bit numbers. If y is one, then the value of x must be the same as z (1&1 = 1; 0&1 = 0). If y is zero, z will also be zero, and x can be either one or zero (0&0 = 0; 1&0 = 0).
On many-bit numbers, every zero bit on y doubles the number of possible values of x, hence 2n
No, simple example
0&0 = 0
1&0 = 0
Let's say I have two items: a unit direction vector, and another arbitrary vector.
What I want to get is the length to make the unit vector so that it covers the "distance" or magnitude of the other vector. So the new vector "contains" the other vector but maintains its direction.
Do you see what I'm saying?
If I understand you correctly (you want vector v):
You want a vector v = (An) where:
(An).b = |b|
Here A is just a number, n is the unit vector and b is the arbitrary vector.
What this means is you want a vector with length A, but if you were to rotate the world so that b was on the x axis, the x component of (An) would be |b| (absolute value of b)
Therefore, in components:
A(n1b1 + n2b2 + n3b3) = sqrt(b1^2 + b2^2 + b3^2)
where n1 means the 1st (x) component of the vector n.
Therefore just re-arrange:
A = sqrt(b1^2 + b2^2 + b3^2)/(n1b1 + n2b2 + n3b3)
A = |b|/(n.b)
So the vector that you're are looking for is:
v = A*n = n * |b|/(n.b)
I believe that's what you want.
Edit: I broke that into components when I REALLY didn't need to. Components are useful if you don't understand what all the terms mean though. But here's it in just vector maths:
An.b = A(n.b) = |b| = abs(b)
A = |b|/(n.b)
Therefore v = An = n * |b|/(n.b)
I have a value, for example 2.8. I want to find 10 numbers which are on an exponential curve, which sum to this value.
That is, I want to end up with 10 numbers which sum to 2.8, and which, when plotted, look like the curve below (exponential decay). These 10 numbers should be equally spaced along the curve - that is, the 'x-step' between the values should be constant.
This value of 2.8 will be entered by the user, and therefore the way I calculate this needs to be some kind of algorithm that I can program (hence asking this on SO not Math.SE).
I have no idea where to start with this at all - any ideas?
You want to have 10 x values equally distributed, i.e. x_k = a + k * b. They shall fulfill sum(exp(-x_k)) = v with v being your target value (the 2.8). This means exp(-a) * sum(exp(-b)^k) = v.
Obviously, there is a solution for each choice of b if v is positive. Set b to an arbitrary value, and calculate a from it.
E.g. for v = 2.8 and b = 0.1, you get a = -log(v / sum(exp(-b)^k)) = -log(2.8/sum(0.90484^k)) = -log(2.8/6.6425) = -log(0.421526) = 0.86387.
So for this example, the x values would be 0.86387, 0.96387, ..., 1.76387 and the y values 0.421526, 0.381412, 0.345116, 0.312274, 0.282557, 0.255668, 0.231338, 0.209324, 0.189404, 0.171380.
Update:
As it has been clarified that the curve can be scaled arbitrarily and the xs are preferred to be 1, 2, 3 ... 9, this is much more simple.
Assuming the curve function is r*exp(-x), the 10 values would be r*exp(-1) ... r*exp(-9). Their sum is r*sum(exp(-x)) = r*0.58190489. So to reach a certain value (2.8) you just have to adjust the r accordingly:
r = 2.8/sum(exp(-x)) = 4.81178294
And you get the 10 values: 1.770156, 0.651204, 0.239565, 0.088131, 0.032422, 0.011927, 0.004388, 0.001614, 0.000594.
If I understand your question correctly then you want to find x which solves the equation
It can be solved as
(just sum numbers as geometric progression)
The equation under RootOf will always have 1 real square different from 1 for 2.8 or any other positive number. You can solve it using some root-finding algorithm (1 is always a root but it does not solve original task). For constant a you can choose any number you like.
After computing the x you can easily calculate 10 numbers as .
I'm going to generalize and assume you want N numbers summing to V.
Since your numbers are equally spaced on an exponential you can write your sum as
a + a*x + a*x^2 + ... + a*x^(N-1) = V
Where the first point has value a, and the second a*x etc.
You can take out a factor of a and get:
a ( 1 + x + x^2 + ... + x^(N-1) ) = V
If we're free to pick x then we can solve for a easily
a = V / ( 1 + x + x^2 + .. x^(N-1) )
= V*(x+1)/(x^N-1)
Substituting that back into
a, a*x, a*x^2, ..., a*x^(N-1)
gives the required sequence
I know the coordinates of A, B and C.. I also know of a vector V originating from C..
I know that the vector intersects A and B, I just don't know how to find i.
Can anyone explain the steps involved in solving this problem?
Thanks alot.
http://img34.imageshack.us/img34/941/triangleprob.png
If you know A and B, you know equation for the line AB, and you said you know V, so you can form the equation for Line V.... Well i is only point that satisfies both those equations.
Equation for Line AB:
(bx-ax)(Y-ay) = (by-ay)(X-ax)
If you knpow the direction (or slope = m) of the vector, and any point that lies on the vector, then the equation of the line for vector V is
Y = mX = b
where m is the slope or direction of the line, and b is the y coordinate where it crosses thevertical y=axis (where X = 0)
if you know a point on the line (i.e., C = (s, t) then you solve for b by:
t = ms + b ==> b = t - ms,
so equation becomes
Y = mX + t-ms
i = C+kV
Lets call N the normal to the line A,B so N = [-(B-A).y, (B-A).x]
Also, for any point on the line:
(P-A)*N = 0 -- substitute from line 1 above:
(C+kV-A)*N = 0
(kV+C-A)*N = 0
kV*N + (C-A)*N = 0
kV*N = (A-C)*N
k = [(A-C)*N]/V*N
Now that we have k, plug it into line 1 above to get i.
Here I'm using * to represent dot product so expanding to regular multiplication:
k = ((A.x-C.x)*-(B.y-A.y) + (A.y-C.y)*(B.x-A.x)) / (V.x*-(B.y-A.y) + V.x*(B.x-A.x))
I.x = C.x + k*V.x
I.y = C.y + k*V.y
Unless I screwed something up....
Simple algebra. The hard part is often just writing down the basic equations, but once written down, the rest is easy.
Can you define a line that emanates from the point C = [c_x,c_y], and points along the vector V = [v_x,v_y]? A nice way to represent such a line is to use a parametric representation. Thus,
V(t) = C + t*V
In terms of the vector elements, we have it as
V(t) = [c_x + t*v_x, c_y + t*v_y]
Look at how this works. When t = 0, we get the point C back, but for any other value of t, we get some other point on the line.
How about the line segment that passes through A and B? One way to solve this problem would be to define a second line parametrically in the same fashion. Then solve for a system of two equations in two unknowns to find the intersection.
An easier approach is to look at the normal vector to the line segment AB. That vector is given as
N = [b_y - a_y , a_x - b_x]/sqrt((b_x - a_x)^2 + (b_y - a_y)^2)
Note that N is defined here to have a unit norm.
So now, when do we know if a point happens to lie along the line that connects A and B? This is easy now. That will happen when the dot product defined below is exactly zero.
dot(N,V(t) - A) = 0
Expand this, and solve for the parameter t. We can write it down using dot products.
t = dot(N,A-C)/dot(N,V)
Or, if you prefer,
t = (N_x*(a_x - c_x) + N_y*(a_y - c_y)) / (N_x*v_x + N_y*v_y))
And once we have t, substitute into the expression above for V(t). Lets see all of this work in practice. I'll pick some points A,B,C and a vector V.
A = [7, 3]
B = [2, 5]
C = [1, 0]
V = [1, 1]
Our normal vector N, after normalization, will look something like
N = [0.371390676354104, 0.928476690885259]
The line parameter, t, is then
t = 3.85714285714286
And we find the point of intersection as
C + t*V = [4.85714285714286, 3.85714285714286]
If you plot the points on a piece of paper it should all fit together, and all in only a few simple expressions.