(You sent this only to me, I suppose that you meant to send to the list, re-adding the list)
Hi, Thanks for the reply! 2009/6/29 Rhys Weatherley <[email protected]>: >> 4. (This one is a nitpick, feel free to ignore) The array is stored as >> a T[][], frankly you're better off storing as a T[] and doing the >> offset computation explicitly, for 2 reasons: 1) the T[][] forces you >> to write weird looking syntax such as in operator+= and data(); 2) if >> you ever want to support dynamically-sized matrices, it'll suddenly >> make a big difference and the only right way will be T[], otherwise >> you'd be allocating a dynamic array for every column. > > Changing it would make every matrix operation turn into a spaghetti of index > multiplications. I prefer the code to be the readable [col][row], with only > a small number of cases using the direct approach. As I said, I was just nitpicking, but you could rely everywhere on inline accessor functions instead of accessing the array directly, so that that would only affect a few lines of code. >> 5. operator== and operator!= should never be used in practice, of >> course, as they do an exact comparision of floating point values which >> is meaningless. I understand that you may have added these operators >> just so that QGenericMatrix's can be used in certain containers. So >> that's ok, but please document clearly the fact that they should never >> be used. By the way if you want proper fuzzy compares for matrices, >> see what we do in Eigen, e.g. isApprox(). > > qFuzzyCompare is provided for this purpose. We discussed this recently inside > Qt Software - both types of comparisons (strict equality and fuzzy) are > useful in different types of algorithms. There was even some admission that > changing QPointF to use qFuzzyCompare in operator== was wrong. OK, then just a loud warning in the documentation telling the user that he probably wants qFuzzyCompare instead... I can believe that there exists a niche for having to do exact comparisons, but it has to be really tiny. Actually I can't think of a valid use case at the moment, but I can trust that you and your fellow Qt engineers had one in mind. In any case, any valid use case would have to be either about dealing directly with the bit representation of floating-point numbers, or dealing with precision levels close to the machine epsilon. Both use cases are pretty niche. My general approach to floating point is rather that one should just not count on using the theoretical precision and instead stay at a respectful distance from it, e.g. rely only on 12 or 13 or 14 significant digits (depending on what one does) when using double's, and then only ever use fuzzy compares. I regard the last bits of the mantissa as just noise. In certain specific contexts (e.g. matrix algorithms) there are empirical formulas saying how many bits are "lost" as noise. > >> 6. Same as 5. in isIdentity() etc. > > (1.00..001 0 0 0 | 0 1 0 0 | 0 0 1 0 | 0 0 0 1) is not the identity matrix and > it would be a mathematical error to treat it as equivalent. A mathematical error, yes. But floating point arithmetic is only a distant cousin to actual real numbers in mathematics. In practice, if you are working with double's and have e.g. (1 1e-14 0 0 | 0 1 0 0 | 0 0 1 0 | 0 0 0 1 ) then in all likeliness the 1e-14 comes from an imprecision in a former computation and is "meant" to be a zero. It is slightly nontrivial to implement a fuzzy isIdentity(), you can find one here: (line 620) http://bitbucket.org/eigen/eigen2/src/tip/Eigen/src/Core/CwiseNullaryOp.h > >> I also have a specific question about QQuaternion: >> >> 7. what is the geometric significance of QQuaternion::vector() and >> setVector()? They seem to be working as if the quaternion was >> interpreted as a homogeneous vector with 4 components; I wonder what >> can be a use case for that ?? Even so, there's a discrepancy: vector() >> returns a vector with the 4th component set to 1, but setVector >> doesn't touch the 4th component? > > vector() returns a QVector3D corresponding to the "vector part" of the > quaternion as opposed to the 4th component "scalar part". Ah, I understand now: in this quaternion representation, the real part is wp, the 4th component. I was expecting it to be the 1st component, which is standard practice (think of complex numbers). Then the wikipedia is on your side, about calling this the "scalar part" and the rest the "vector part": http://en.wikipedia.org/wiki/Quaternion#Scalar_and_vector_parts Cheers, Benoit _______________________________________________ Qt4-preview-feedback mailing list [email protected] http://lists.trolltech.com/mailman/listinfo/qt4-preview-feedback
