Determine Quaternion Which Sends One Vector into Another - algorithm

First off, this is not a duplicate. All other seemingly related questions ask for the quaternion representing rotation between directions of 2 vectors, i.e. the solutions do not take into account norms of these 2 vectors.
Here is what I want. Imagine that I have non-unit vectors a = (0, 0, 2) and b = (3, 1, 2). Following the original Hamilton's definition of quaternion q = a / b (this definition is symbolic, since of course you cannot divide vectors). Refer to Wikipedia for this concept. From that I can infer (maybe it's naive) that somehow I can find such q that q * b = a.
In other words, given a and b I want to find a quaternion q which when multiplied by b will give me a. Please, pay attention to the fact that I'm not interested in plain rotating (unitary) quaternion which would simply rotate b into direction of a. In fact, in addition to rotation, I want norm of b to be scaled to the norm of a as well.
Yes, I know that I could do it in two stages: rotating b with standard unitary quaternion approach and then manually scaling the rotated b to the norm of a which would of course involve additional square roots (which is what I'm trying to avoid here). In fact, I want a computationally efficient composition of these 2 operations, and I feel like it's achievable, but the information is not widespread since it does not seem to be conventional use case.
Maybe I'm wrong. Please, share your experiences. Thank you.
Why not math.stackexchange.com?
Because I'm not interested in thorough mathematical derivation or explanation. My concern is computationally efficient algorithm for construction of such quaternion. Nevertheless, if such details will be included in the answer, I'd really appreciate that and probably others who stumble across the same issue in future too.
For Close Voters:
Go ahead and close Finding quaternion representing the rotation from one vector to another as well.
Furthermore, I have tagged my question properly. My question belongs to these highly-populated tags which are part of StackOverflow. As a result, your reasons for close do not make any sense.

Daniel Fischer's comment-answer is correct. It turns out that there are infinite ways to construct such a quaternion. The problem boils down to a linear system with three equations and four variables. It's under-constrained (if we assume we'll discard the [w] part of the result).
Perhaps I can clarify Fischer's answer.
When you treat two vectors as quaternions and multiply them, you get their cross-product in the [x,y,z] part and you get their negated dot-product in the [w] part:
| 0| | 0| |-ax*bx-ay*by-az*bz|
a*b=|ax|*|bx|=| ay*bz-az*by |
|ay| |by| | az*bx-ax*bz |
|az| |bz| | ax*by-ay*bx |
When you left-multiply a full-quaternion with a vector, you get the same thing, but the [w] part scales the vector and adds it back to the cross-product:
|qw| | 0| |-qx*bx-qy*by-qz*bz|
q*b=|qx|*|bx|=| qy*bz-qz*by+qw*bx|
|qy| |by| | qz*bx-qx*bz+qw*by|
|qz| |bz| | qx*by-qy*bx+qw*bz|
Recall that
a x b = |a||b|sin(Θ)n
where n is a unit vector that is orthogonal to a and b. And
a . b = |a||b|cos(Θ)
The quaternion conjugate of a vector is just its negation.
So if we look at Fischer's equation:
a = q*b = |b|^{-2} * a * b' * b
We can see that
a*b' = | -dotP(a,-b)|
|crossP(a,-b)|
And so
a*b'*b = | -dotP(crossP(a,-b),b) |
| crossP(crossP(a,-b),b) - dotP(a,-b)b |
The top ([w]) portion of this quaternion must be zero because it is the dot-product between two orthogonal vectors. The bottom portion is a scaled version of a: The nested cross-products produce a vector that is orthogonal to both b and n and is the length of |a|*|b|*|b|. The dot-product portion adds in the projection of a onto b (scaled by the squared length of b). This brings it parallel to a. Once we divide out the squared length of b, all that's left is a.
Now, the question of whether or not this is actually useful is different. It's not very useful to finding a, since you need to have it to begin with. Furthermore, odds are good that q*c is not going to do what you're hoping, but you'd have to tell us what that is.

Related

Querying large amount of multidimensional points in R^N

I'm looking at listing/counting the number of integer points in R^N (in the sense of Euclidean space), within certain geometric shapes, such as circles and ellipses, subject to various conditions, for small N. By this I mean that N < 5, and the conditions are polynomial inequalities.
As a concrete example, take R^2. One of the queries I might like to run is "How many integer points are there in an ellipse (parameterised by x = 4 cos(theta), y = 3 sin(theta) ), such that y * x^2 - x * y = 4?"
I could implement this in Haskell like this:
ghci> let latticePoints = [(x,y) | x <- [-4..4], y <-[-3..3], 9*x^2 + 16*y^2 <= 144, y*x^2 - x*y == 4]
and then I would have:
ghci> latticePoints
[(-1,2),(2,2)]
Which indeed answers my question.
Of course, this is a very naive implementation, but it demonstrates what I'm trying to achieve. (I'm also only using Haskell here as I feel it most directly expresses the underlying mathematical ideas.)
Now, if I had something like "In R^5, how many integer points are there in a 4-sphere of radius 1,000,000, satisfying x^3 - y + z = 20?", I might try something like this:
ghci> :{
Prelude| let latticePoints2 = [(x,y,z,w,v) | x <-[-1000..1000], y <- [-1000..1000],
Prelude| z <- [-1000..1000], w <- [-1000..1000], v <-[1000..1000],
Prelude| x^2 + y^2 + z^2 + w^2 + v^2 <= 1000000, x^3 - y + z == 20]
Prelude| :}
so if I now type:
ghci> latticePoints2
Not much will happen...
I imagine the issue is because it's effectively looping through 2000^5 (32 quadrillion!) points, and it's clearly unreasonably of me to expect my computer to deal with that. I can't imagine doing a similar implementation in Python or C would help matters much either.
So if I want to tackle a large number of points in such a way, what would be my best bet in terms of general algorithms or data structures? I saw in another thread (Count number of points inside a circle fast), someone mention quadtrees as well as K-D trees, but I wouldn't know how to implement those, nor how to appropriately query one once it was implemented.
I'm aware some of these numbers are quite large, but the biggest circles, ellipses, etc I'd be dealing with are of radius 10^12 (one trillion), and I certainly wouldn't need to deal with R^N with N > 5. If the above is NOT possible, I'd be interested to know what sort of numbers WOULD be feasible?
There is no general way to solve this problem. The problem of finding integer solutions to algebraic equations (equations of this sort are called Diophantine equations) is known to be undecidable. Apparently, you can write equations of this sort such that solving the equations ends up being equivalent to deciding whether a given Turing machine will halt on a given input.
In the examples you've listed, you've always constrained the points to be on some well-behaved shape, like an ellipse or a sphere. While this particular class of problem is definitely decidable, I'm skeptical that you can efficiently solve these problems for more complex curves. I suspect that it would be possible to construct short formulas that describe curves that are mostly empty but have a huge bounding box.
If you happen to know more about the structure of the problems you're trying to solve - for example, if you're always dealing with spheres or ellipses - then you may be able to find fast algorithms for this problem. In general, though, I don't think you'll be able to do much better than brute force. I'm willing to admit that (and in fact, hopeful that) someone will prove me wrong about this, though.
The idea behind the kd-tree method is that you recursive subdivide the search box and try to rule out whole boxes at a time. Given the current box, use some method that either (a) declares that all points in the box match the predicate (b) declares that no points in the box match the predicate (c) makes no declaration (one possibility, which may be particularly convenient in Haskell: interval arithmetic). On (c), cut the box in half (say along the longest dimension) and recursively count in the halves. Obviously the method can choose (c) all the time, which devolves to brute force; the goal here is to do (a) or (b) as much as possible.
The performance of this method is very dependent on how it's instantiated. Try it -- it shouldn't be more than a couple dozen lines of code.
For nicely connected region, assuming your shape is significantly smaller than your containing search space, and given a seed point, you could do a growth/building algorithm:
Given a seed point:
Push seed point into test-queue
while test-queue has items:
Pop item from test-queue
If item tests to be within region (eg using a callback function):
Add item to inside-set
for each neighbour point (generated on the fly):
if neighbour not in outside-set and neighbour not in inside-set:
Add neighbour to test-queue
else:
Add item to outside-set
return inside-set
The trick is to find an initial seed point that is inside the function.
Make sure your set implementation gives O(1) duplicate checking. This method will eventually break down with large numbers of dimensions as the surface area exceeds the volume, but for 5 dimensions should be fine.

Find points given distances between them

Here is an example:
Suppose there are 4 points: A, B, C, and D
Given that Point A is at (0,0):
and the distances:
A to B: 7
A to C: 5
A to D: 9
B to C: 6
B to D: 5
C to D: 7
The goal would be to find a solution to points B(x,y), C(x,y) and D(x,y)
What is an algorithm to find the points ( up to 50 of them ) given the distances between them?
OK,you have 4 points A, B, C, and D which are separated from one another such that the lengths of the distances between each pair of points is AB=7, AC=5, BC=6, AD=9, BD=5, and CD=7. Axyz=(0,0,0), Bxyz=(7,0,0), Cxyz=(2.7,4.2,0), Dxyz=(7.5,1.9,4.6) (rounding to the first decimal).
We set point A at the origin Axyz= (0,0,0).
We set point B at x=7,y=0,z=0 Bxyz= (7,0,0).
We find the x coordinate for point C by using the law of cosines:
((AB^2+AC^2-BC^2)/2)/Bx = Cx
((7^2+5^2-6^2)/2)/7=
((49+25-36)/2)/7= 38/14 = 2.714286
We then use the pythagorean theorem to find Cy:
sqrt(AC^2-Cx^2)=Cy
sqrt(25-7.367347)=4.199
So Cxyz=(2.714,4.199,0)
We find Dx in much the same way we found Cx:
((AB^2+AD^2-BD^2)/2)/Bx =Dx
((49+81-25)/2)/7= 7.5 = Dx
We find Dy by a slightly different formula:
(((AC^2+AD^2-CD^2)/2)-(Cx*Dx))/Dy
(((25+81-49)/2)-(2.714*7.5))/4.199= 1.94 (approx)
Having found Dx and Dy, we can find Dz by using Pythagorean theorem:
sqrt(AD^2-Dx^2-Dy^2)=
sqrt(9^2-7.5^2-1.94^2) = 4.58
So Dxyz=(7.5, 1.94, 4.58)
If you have pairwise distances between each of a set of 50 points, then you might need as many as 49 dimensions in order to obtain coordinates for all the points. If A, B, C, D, and E are all separated by 10 lengths units from each of every other, then you would need 4 spatial dimensions - if you introduce another point (F) which is also equidistant from all the other points, then you will need 5 dimensions. The algorithm works the same no matter how many dimensions are necessary (and in fact it works best when the maximum number of dimensions IS required-). The algorithm also works when the distances violate the triangle rule - such as if AB=3, AC=4, and BC=13 - the coordinates are A=0,0; B=3,0; and C=-24,23.66i. If the triangle rule is violated, then some of the coordinates will simply be imaginary valued. No big deal.
In general for point G, the coordinates (x1st, x2nd, x3rd, x4th, x5th, and x6th) can be found thusly:
G1st=((AB^2+AG^2-BG^2)/2)/(B1st)
G2nd=(((AC^2+AG^2-CG^2)/2)-(C1st*G1st))/(C2nd)
G3rd=(((AD^2+AG^2-DG^2)/2)-(D1stG1st)-(D2ndG2nd))/(D3rd)
G4th=(((AE^2+AG^2-EG^2)/2)-(E1stG1st)-(E2ndG2nd)-(E3rd*G3rd))/(E4th)
G5th=(((AF^2+AG^2-FG^2)/2)-(F1stG1st)-(F2ndG2nd)-(F3rdG3rd)-(F4thG4th))/(F5th)
G6th=sqrt(AG^2-G1st^2-G2nd^2-G3rd^2-G4th^2-G5th^2)
For the 5th point you find the first three coordinates with lawofcosine calculations and you find the 4th coordinate with a pythagoreantheorem calculations. For the 6th point you find the first 4 coordinates with 4 lawofcosine calculations and then you obtain the final coordinate with the pythagoreantheorem calculation. For the 50th point, you find the first 48 coordinates with 48 lawofcosines calculations and the 49th coordinate is found with a pythagoreantheorem calculation. So for 50 points, there will be 48 pythagoreantheorem calculations altogether plus 1128 lawofcosine calculations.
The algorithm is fairly straightforward:
A is always set at the origin and B is set at x=AB (or rather B1st=AB)
C1st is found by using the law of cosines ((AB^2+AC^2-BC^2)/2)/(B1st)
C2nd is then found with pythagorean theorem (sqrt(AC^2-C1st^2))
BUT WHAT IF C2nd = 0? This is not necessarily a problem, but it can become a problem for finding D2nd, D3rd, E2nd, E3rd, E4th, etc.
If AB=4, AC=8, BC=4, then we will obtain A (0,0), B (4,0), and C (8,0). If AD=4, BD=8, and CD=12, then there will be no problem for finding coordinates for D which would be D (-4,0).
However, if CD is not equal to 12, then we WILL have a problem. For instance, if CD=5, then we might find that we should go back and calculate coordinates for the points in a different order such as ACDB, that way we can get A=(0,0,0);C=(8,0,0); D=(3.44,2.04,0); and B=(4,-14.55,14.55i). This is a fairly intuitive solution, but it interrupts the flow of the algorithm because we have to go backwards and start over in a different order.
Another solution to the problem which does not necessitate interrupting the flow of computations is to deliberately introduce an error whenever a pythagoreantheorem calculation gives us a zero. -- Instead of a zero, put a 0.1 or 0.01 as the C2nd coordinate. This will allow one to proceed with calculating coordinates for the remaining points without interruption and the accuracy of the final results will suffer only a little (truth be told the algorithm is subject to cumulative rounding errors anyhow, so its no big deal). Also the deliberate introduction of error is the only way to obtain a solution at all in some cases:
Consider once again 4 points A, B, C, and D with distances such the AB=4, AC=8, BC=4, AD=4, BD=8, and CD=4 (we previously have had CD at 12, and CD at 5). When CD=4, there IS NO exact solution no matter what order you calculate the points. Go ahead and try.
A=(0,0,0), B=(4,0,0), C=(8,0,0)... If you introduce an error at C2nd so that instead of zero you put 0.1 such that C=(8,0.1,0), then you can obtain a solution for point D's coordinates D=(-4,640,640i). If you introduce a smaller error for C2nd such that C=(8,0.01,0), then you get D=(-4,6400,6400i). As C2nd gets closer and closer to zero, D2nd, and D3rd just get farther and farther away along the same direction. A similar result occurs sometimes when the distance between two points is close to zero. The algorithm ofcourse will not work with a distance that is actually equal to zero such with AB=5,AC=8, and BC=0. But it will work with BC=0.000001.
Anyway, I think this has answered your question you asked a year ago.

what is the right algorithm for ... eh, I don't know what it's called

Suppose I have a long and irregular digital signal made up of smaller but irregular signals occurring at various times (and overlapping each other). We will call these shorter signals the "pieces" that make up the larger signal. By "irregular" I mean that it is not a specific frequency or pattern.
Given the long signal I need to find the optimal arrangement of pieces that produce (as closely as possible) the larger signal. I know what the pieces look like but I don't know how many of them exist in the full signal (or how many times any one piece exists in the full signal). What software algorithm would you use to do this optimization? What do I search for on the web to get help on solving this problem?
Here's a stab at it.
This is actually the easier of the deconvolution problems. It is easier in that you may be able to have a unique answer. The harder problem is that you also don't know what the pieces look like. That case is called blind deconvolution. It is a harder problem and is usually iterative and statistical (ML or MAP), and the solution may not be right.
Luckily, your case is easier, but still not so easy because you have multiple pieces :p
I think that it may be commonly called mixture deconvolution?
So let f[t] for t=1,...N be your long signal. Let h1[t]...hn[t] for t=0,1,2,...M be your short signals. Obviously here, N>>M.
So your hypothesis is that:
(1) f[t] = h1[t+a1[1]]+h1[t+a1[2]] + ...
+h2[t+a2[1]]+h2[t+a2[2]] + ...
+....
+hn[t+an[1]]+h2[t+an[2]] + ...
Observe that each row of that equation is actually hj * uj where uj is the sum of shifted Kronecker delta. The * here is convolution.
So now what?
Let Hj be the (maybe transposed depending on how you look at it) Toeplitz matrix generated by hj, then the equation above becomes:
(2) F = H1 U1 + H2 U2 + ... Hn Un
subject to the constraint that uj[k] must be either 0 or 1.
where F is the vector [f[0],...F[N]] and Uj is the vector [uj[0],...uj[N]].
So you can rewrite this as:
(3) F = H * U
where H = [H1 ... Hn] (horizontal concatenation) and U = [U1; ... ;Un] (vertical concatenation).
H is an Nx(nN) matrix. U is an nN vector.
Ok, so the solution space is finite. It is 2^(nN) in size. So you can try all possible combinations to see which one gives you the lowest ||F - H*U||, but that will take too long.
What you can do is solve equation (3) using pseudo-inverse, multi-linear regression (which uses least square, which comes out to pseudo-inverse), or something like this
Is it possible to solve a non-square under/over constrained matrix using Accelerate/LAPACK?
Then move that solution around within the null space of H to get a solution subject to the constraint that uj[k] must be either 0 or 1.
Alternatively, you can use something like Nelder-Mead or Levenberg-Marquardt to find the minimum of:
||F - H U|| + lambda g(U)
where g is a regularization function defined as:
g(U) = ||U - U*||
where U*[j] = 0 if |U[j]|<|U[j]-1|, else 1
Ok, so I have no idea if this will converge. If not, you have to come up with your own regularizer. It's kinda dumb to use a generalized nonlinear optimizer when you have a set of linear equations.
In reality, you're going to have noise and what not, so it actually may not be a bad idea to use something like MAP and apply the small pieces as prior.

Algorithm for superimposition of 3d points

I need to superimpose two groups of 3D points on top of each other; i.e. find rotation and translation matrices to minimize the RMSD (root mean square deviation) between their coordinates.
I currently use Kabsch algorithm, which is not very useful for many of the cases I need to deal with. Kabsch requires equal number of points in both data sets, plus, it needs to know which point is going to be aligned with which one beforehand. For my case, the number of points will be different, and I don't care which point corresponds to which in the final alignment, as long as the RMSD is minimized.
So, the algorithm will (presumably) find a 1-1 mapping between the subsets of two point sets such that AFTER rotation&translation, the RMSD is minimized.
I know some algorithms that deal with different number of points, however they all are protein-based, that is, they try to align the backbones together (some continuous segment is aligned with another continuous segment etc), which is not useful for points floating in space, without any connections. (OK, to be clear, some points are connected; but there are points without any connections which I don't want to ignore during superimposition.)
Only algorithm that I found is DIP-OVL, found in STRAP software module (open source). I tried the code, but the behaviour seems erratic; sometimes it finds good alignments, sometimes it can't align a set of few points with itself after a simple X translation.
Anyone know of an algorithm that deals with such limitations? I'll have at most ~10^2 to ~10^3 points if the performance is an issue.
To be honest, the objective function to use is not very clear. RMSD is defined as the RMS of the distance between the corresponding points. If I have two sets with 50 and 100 points, and the algorithm matches 1 or few points within the sets, the resulting RMSD between those few points will be zero, while the overall superposition may not be so great. RMSD between all pairs of points is not a better solution (I think).
Only thing I can think of is to find the closest point in set X for each point in set Y (so there will be exactly min(|X|,|Y|) matches, e.g. 50 in that case) and calculate RMSD from those matches. But the distance calculation and bipartite matching portion seems too computationally complex to call in a batch fashion. Any help in that area will help as well.
Thanks!
What you said looks like a "cloud to cloud registration" task. Take a look into http://en.wikipedia.org/wiki/Iterative_closest_point and http://www.willowgarage.com/blog/2011/04/10/modular-components-point-cloud-registration for example. You can play with your data in open source Point Cloud Library to see if it works for you.
If you know which pairs of points correspond to each other, you can recover the transformation matrix with Linear Least Squares (LLS).
When considering LLS, you normally would want to find an approximation of x in A*x = b. With a transpose, you can solve for A instead of x.
Extend each source and target vector with "1", so they look like <x, y z, 1>
Equation: A · xi = bi
Extend to multiple vectors: A · X = B
Transpose: (A · X)T = BT
Simplify: XT · AT = BT
Substitute P = XT, Q = AT and R = BT. The result is: P · Q = R
Apply the formula for LLS: Q ≈ (PT · P)-1 · PT · R.
Substitute back: AT ≈ (X · XT)-1 · X · BT
Solve for A, and simplify: A ≈ B · XT · (X · XT)-1
(B · XT) and (X · XT) can be computed iteratively by summing up the outer products of the individual vector pairs.
B · XT = ∑bi·xiT
X · XT = ∑xi·xiT
A ≈ (∑bi·xiT) · (∑xi·xiT)-1
No matrix will be bigger than 4×4, so the algorithm does not use any excessive memory.
The result is not necessarily affine, but probably close. With some further processing, you can make it affine.
The best algorithm for discovering alignments through superimposition is Procrustes Analysis or Horn's method. Please follow this Stackoverflow link.

3D Rigid Registration - Minimal Points Analytic Solution - How to Build Rotation Matrices?

I have two sets of three (non-collinear) points, in three dimensions. I know the correspondence between the points - i.e. set 1 is {A, B, C} and set 2 is {A', B', C'}.
I want to find the combination of translation and rotation that will transform A' to A, B' to B, and C' to C. Note: There is no scaling involved. (I know this for certain, although I am curious about how to handle it if it did exist.)
I found what looks like a solid explanation while trying to work out how to do this. Section 2 (page 3) entitled "Three Point Registration" appears to be what I need to do. I understand steps 1 through 4 and 6 through 7 just fine, but 5 has me stumped.
5. Build the rotation matrices for both point sets:
Rl = [xl, yl, zl], Rr = [xr, yr, zr]
How do I do that???
Later I plan to implement a least squares solution, but I want to do this first.
this document appears to have an identical copy of that section, but following that is a worked example. i must admit that it's still not clear to me how the step works, but you may find it clearer than me.
update: column 1 of Rl is the x axis constructed earlier ([0,1,0] in terms of the original axes). so i imagine that x, y and z are the axes, as column vectors. which makes sense... and i assume Rr is the same in the other coordinate system.
is that clear?
I'll take a stab at it.
each point gets an equation: a_1x + b_1y + c_1z = d_1, right, so make 2 3x3 matrices of the
a,b,c values.
then, since each point is independent of one another, you can solve for the transform between the two matrices, A and A'
T A = A'
After some linear algebra,
T = A' inv(A)
Try it in MATLAB and let us know.

Resources