-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stddev calculations #5
Conversation
@Juanlu001 @gilgamezh como arreglo esto? |
@enritoomey , creo que hay que mergear primero el PR de @gilgamezh para que travis sepa de qué se trata el proyecto. |
@henry-aocs please merge master to this branch to get the tests working |
3 similar comments
el covarage da bajo porque agregue una funcion que no testeo.... en el proximo commit le agrego el test y saco el wip |
@gilgamezh @matiasg estoy esperando su +1 |
@Juanlu001, queres darle una mirada a este MR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Despite some minor comments and typos this looks good to me, however bear in mind that I didn't review the math in depth. There are lots of tests against MATLAB though, which is very nice.
quaternions/quaternions.py
Outdated
@@ -1,7 +1,7 @@ | |||
import functools | |||
import numpy as np | |||
from collections import Iterable | |||
|
|||
from quaternions.utils import (covariance_matrix_from_angles, sigma_lerner, orthogonal_matrix) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to have parentheses here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, but i was @matiasg style to put then anyway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parentheses there are needed when you need to split into multiple lines. Otherwise, they are not.
I'm not saying that I always go by this rule, but it's the best rule I can produce ;-)
quaternions/quaternions.py
Outdated
''' | ||
Return the quaternion such that its matrix minimizes the square distance | ||
to the matrices of the quaternions in the argument list. | ||
|
||
See Averaging Quaternions, by Markley, Cheng, Crassidis, Oschman. | ||
''' | ||
B = np.array([q.coordinates for q in quaternions]) | ||
if not weights: | ||
if not any(True for _ in weights): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this instead of the empty list/tuple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change it to: use None as default value for weights, and then check if weights is None
.
quaternions/quaternions.py
Outdated
Naive implementation of std. dev. calculation, assuming small angles between quaternions | ||
and average. Returns average quaternion and stddev of input quaternion list in deg | ||
""" | ||
if not any(True for _ in weights): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
quaternions/quaternions.py
Outdated
weights = np.ones(len(quaternions)) | ||
q_average = Quaternion.average(*quaternions, weights=weights) | ||
diffs = np.array([q_average.distance(quat) for quat in quaternions]) | ||
# TODO: check that this way of taking into account weights in stddev calculation is ok |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say it's ok!
quaternions/quaternions.py
Outdated
called sigma lerner. This covariance matriz is the one asociated with the rotation angles of | ||
each input quaternion agains the average one. Returns the average quaternion anf the sigma lerner | ||
in deg. | ||
:param quaternions: lista de objetos Quaternion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Se escapó un comentario en español :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yo no hablar español... jajja, ahora lo corrigo
quaternions/quaternions.py
Outdated
@staticmethod | ||
def average_and_std_lerner(*quaternions, weights=()): | ||
""" | ||
Calculates the std. dev. as 1.87 of the root of the maximum eigenvalue of the covariance matrix, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not an expert on quaternions, but Google didn't show any relevant results on "quaternions" "sigma lerner"
and variations. Perhaps it's coming from some article by Gerald M. Lerner? Is there a chance we can document this a bit more?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
certainly, i have to track down the paper from which this way of condensing a correlation matrix to a single value was taken...
quaternions/quaternions.py
Outdated
def average_and_std_lerner(*quaternions, weights=()): | ||
""" | ||
Calculates the std. dev. as 1.87 of the root of the maximum eigenvalue of the covariance matrix, | ||
called sigma lerner. This covariance matriz is the one asociated with the rotation angles of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"matriz", "anf"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
quaternions/quaternions.py
Outdated
orthogonal_matrix_sum += orthogonal_matrix(q).dot( | ||
R_inverse.dot(orthogonal_matrix(q).T)) | ||
|
||
cov_dev_matrix = np.linalg.inv(orthogonal_matrix(q_average).T.dot( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the code is required to run in Python 3.4? Otherwise you could use orthogonal_matrix(q_average).T @ orthogonal_matrix_sum @ orthogonal_matrix(q_average)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeap, I still fun python 3.4 in my debian8 installation 😳 Do we have a requisite on the python version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have travis now, that tests the code from python 3.4 until 3.6.
And 3.4 is needed, sadly.
quaternions/utils.py
Outdated
""" | ||
covariance_matrix = np.zeros((3, 3)) | ||
for angles in angles_list: | ||
covariance_matrix += np.outer(angles.T, angles) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess angles_list
is a list of NumPy arrays, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
tests/test_quaternions.py
Outdated
* np.sqrt(len(quat_diff_matlab_quats)-1) | ||
|
||
assert abs(sigma_lerner_in_deg - sigma_lerner_out_deg ) \ | ||
< self.tolerance_deg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing newline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although it would be nice to know from which Lerner paper does the covariance come, I'm approving these changes.
...although some tests fail in Python 3.6 :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should first merge the PR splitting quaternions into two classes and then merge this one. Anyway, there should be almost no changes in this PR for that.
Mostly, I'd like some function names to change.
@@ -0,0 +1,38 @@ | |||
import numpy as np |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please, add the reference to the paper(s) you are implementing here.
Also, in the methods, there could be a line like equation 2.3 from (1)
, or any other citation like this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still missing the reference paper to the sigma lerner calculation
quaternions/utils.py
Outdated
[-quaternion.qj, quaternion.qi, 0]]) | ||
|
||
|
||
def orthogonal_matrix(quaternion): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I strongly oppose to this name :-P
This matrix is not square, so it is not an orthogonal matrix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
quaternions/utils.py
Outdated
return 1.87 * np.sqrt(max(values)) | ||
|
||
|
||
def rotation_matrix(quaternion): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not a rotation matrix, but the matrix of a cross product with the vector [qi, qj, qk]
.
The name cross_product_matrix
might be better. It could also have the same name it has in the paper where it comes from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
1 similar comment
1 similar comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok for me after a few changes are made.
quaternions/quaternion.py
Outdated
weights = np.ones(len(quaternions)) | ||
q_average = Quaternion.average(*quaternions, weights=weights) | ||
diffs = np.array([q_average.distance(quat) for quat in quaternions]) | ||
# TODO: check that this way of taking into account weights in stddev calculation is ok |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is what you do with any zero-mean random variable to compute its standard deviation:
sqrt( sum ( x ** 2 * p(x) ) )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
quaternions/quaternion.py
Outdated
@staticmethod | ||
def average_and_std_naive(*quaternions, weights=None): | ||
""" | ||
Naive implementation of std. dev. calculation, assuming small angles between quaternions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you need small angles?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't know why I put that docstring.
quaternions/quaternion.py
Outdated
""" | ||
q_average = Quaternion.average(*quaternions, weights=weights) | ||
diffs = [quat / q_average for quat in quaternions] | ||
angles_list = np.array([[2 * diff.coordinates[i] for i in [1, 2, 3]] for diff in diffs]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can do here
angles_list = [2 * diff.coordinates[1:] for diff in diffs]
You don't need it to be a numpy array, anyway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, the RAX
paper works with Gibbs vectors, which are
diff.coordinates[1:] / diff.qr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, actually there's a factor of two. I'll open an issue
quaternions/quaternion.py
Outdated
""" | ||
Calculates the std. dev. as 1.87 of the root of the maximum eigenvalue of the covariance matrix, | ||
called sigma lerner. This covariance matrix is the one asociated with the rotation angles of | ||
each input quaternion agains the average one. Returns the average quaternion and the sigma lerner |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
against
quaternions/utils.py
Outdated
""" | ||
covariance_matrix = np.zeros((3, 3)) | ||
for angles in angles_list: | ||
covariance_matrix += np.outer(angles.T, angles) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems that these three lines can be
covariance_matrix = sum(np.outer(angles, angles) for angles in angles_list)
or, if you already receive a numpy.array
, by
covariance_matrix = angles_list.T.dot(angles_list)
quaternions/quaternion.py
Outdated
Returns the quaternion such that its matrix minimizes the square distance | ||
to the matrices of the quaternions in the argument list, and the resulting | ||
covariance matrix asociated with that quaternion. Input matrix R (3x3) is | ||
assume to be the same for all input quaternions, and in rads**2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assumed
quaternions/quaternion.py
Outdated
''' | ||
Returns the quaternion such that its matrix minimizes the square distance | ||
to the matrices of the quaternions in the argument list, and the resulting | ||
covariance matrix asociated with that quaternion. Input matrix R (3x3) is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
associated
3 similar comments
# This is the 1st commit message: pin coveralls version # This is the commit message #2: rever change of pytest-coverage. Pin python-coverage # This is the commit message #3: just as a test, remove coveralls # This is the commit message #4: remove also cov from script 🤦 # This is the commit message #5: pin pytest version # This is the commit message #6: pin hypothesis version # This is the commit message #7: pin hypothesis to 3.55.1 now # This is the commit message #8: do not install pytest-coverage # This is the commit message #9: pin pytest-coverage # This is the commit message #10: install pinned coverage, do not install pytest-coverage :'( # This is the commit message #11: pin attr # This is the commit message #12: attr is attrs # This is the commit message #13: travis, please tell me attr version # This is the commit message #14: go back to original setup.py # This is the commit message #15: exclude coveralls from 3.4 & 3.5. Try 1 # This is the commit message #16: use [] instead of test # This is the commit message #17: install pytest 5.4.3 # This is the commit message #18: travis tell me something # This is the commit message #19: please do tell # This is the commit message #20: ooohhh? # This is the commit message #21: oh 2 # This is the commit message #22: oh 3 # This is the commit message #23: oh 4 # This is the commit message #24: oh 5
No description provided.