001/**
002 * ParamTestSuite -- An suite of unit tests for the jahuwaldt.js.param package.
003 * 
004 * Copyright (C) 2014 by Joseph A. Huwaldt. All rights reserved.
005 * 
006 * This library is free software; you can redistribute it and/or modify it under the terms
007 * of the GNU Lesser General Public License as published by the Free Software Foundation;
008 * either version 2 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
012 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
013 * 
014 * You should have received a copy of the GNU Lesser General Public License along with
015 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place -
016 * Suite 330, Boston, MA 02111-1307, USA. Or visit: http://www.gnu.org/licenses/lgpl.html
017 */
018package jahuwaldt.js.param;
019
020import jahuwaldt.tools.math.MathTools;
021import javax.measure.converter.UnitConverter;
022import javax.measure.quantity.Angle;
023import javax.measure.quantity.Dimensionless;
024import javax.measure.quantity.Length;
025import javax.measure.unit.NonSI;
026import javax.measure.unit.SI;
027import javax.measure.unit.Unit;
028import javolution.lang.MathLib;
029import javolution.testing.TestCase;
030import javolution.testing.TestContext;
031import javolution.testing.TestSuite;
032import javolution.text.TextBuilder;
033import org.jscience.mathematics.number.Float64;
034import org.jscience.mathematics.vector.Float64Matrix;
035import org.jscience.mathematics.vector.Float64Vector;
036
037
038/**
039 * <p> This class holds the {@link jahuwaldt.js.param} package unit tests and benchmarks.</p>
040 * 
041 * <p> Modified by: Joseph A. Huwaldt </p>
042 * 
043 * @author Joseph A. Huwaldt Date: February 27, 2014
044 * @version March 1, 2014
045 */
046public final class ParamTestSuite extends TestSuite {
047    
048    @Override
049    public void run() {
050        TestContext.info("-----------------------------------------------");
051        TestContext.info("-- Test Suite for jahuwaldt.js.param package --");
052        TestContext.info("-----------------------------------------------");
053        TestContext.test(new ParameterGetValue(100, NonSI.INCH, NonSI.YARD));
054        TestContext.test(new ParameterToUnit(NonSI.FOOT, SI.METER));
055        TestContext.test(new ParameterBasicMathOperations());
056        TestContext.test(new ParameterLogicalComparisons());
057        TestContext.test(new DCMatrixTests());
058        TestContext.test(new QuaternionTests());
059    }
060    
061    @Override
062    public CharSequence getDescription() {
063        return TextBuilder.newInstance().append("Test Suite for the jahuwaldt.js.param package.");
064    }
065    
066    public static class ParameterGetValue extends TestCase {
067        private final int _numValues;
068        private final Unit _fromUnit;
069        private final Unit _toUnit;
070        private final double[] _values;
071        private final Parameter[] _params;
072        
073        public ParameterGetValue(int numValues, Unit fromUnit, Unit toUnit) {
074            _numValues = numValues;
075            _fromUnit = fromUnit;
076            _toUnit = toUnit;
077            _values = new double[numValues];
078            _params = new Parameter[numValues];
079        }
080        
081        @Override
082        public CharSequence getDescription() {
083            return TextBuilder.newInstance().append("Parameter.getValue(unit)");
084        }
085        
086        @Override
087        public void prepare() {
088            for (int i=0; i < _numValues; ++i) {
089                _params[i] = Parameter.valueOf(MathLib.random()*10,_fromUnit);
090            }
091        }
092        
093        @Override
094        public int count() {
095            return _numValues;
096        }
097        
098        @Override
099        public void execute() {
100            for (int i=0; i < _numValues; ++i) {
101                _values[i] = _params[i].getValue(_toUnit);
102            }
103        }
104        
105        @Override
106        public void validate() {
107            UnitConverter cvtr = Parameter.converterOf(_fromUnit, _toUnit);
108            for (int i=0; i < _numValues; ++i) {
109                double expected = cvtr.convert(_params[i].getValue());
110                TestContext.assertEquals(expected, _values[i]);
111            }
112        }
113        
114    }
115
116    public static class ParameterToUnit extends TestCase {
117        private static final double FROMVALUE = 2;
118        private final Unit _fromUnit;
119        private final Unit _toUnit;
120        private Parameter _param;
121        private Parameter _toParam;
122        
123        public ParameterToUnit(Unit fromUnit, Unit toUnit) {
124            _fromUnit = fromUnit;
125            _toUnit = toUnit;
126        }
127        
128        @Override
129        public CharSequence getDescription() {
130            return TextBuilder.newInstance().append("Parameter.to(Unit): from = ")
131                    .append(_fromUnit).append(", to = ").append(_toUnit);
132        }
133        
134        @Override
135        public void prepare() {
136            _param = Parameter.valueOf(FROMVALUE, _fromUnit);
137        }
138        
139        @Override
140        public void execute() {
141            _toParam = _param.to(_toUnit);
142        }
143        
144        @Override
145        public void validate() {
146            UnitConverter cvtr = Parameter.converterOf(_fromUnit, _toUnit);
147            Parameter expected = Parameter.valueOf(cvtr.convert(FROMVALUE),_toUnit);
148            TestContext.assertEquals(expected, _toParam);
149        }
150        
151    }
152
153    public static class ParameterBasicMathOperations extends TestCase {
154        private static final Unit unit = NonSI.FOOT;
155        private static final double P1VALUE = -3.14159;
156        private static final double P2VALUE = 42;
157        private static final double P3VALUE = 223;
158        private static final double K = 2;
159        private final Parameter<Length> p1 = Parameter.valueOf(P1VALUE,unit);
160        private final Parameter<Length> p2 = Parameter.valueOf(P2VALUE,unit);
161        private final Parameter<Angle> p3 = Parameter.valueOf(P3VALUE, NonSI.DEGREE_ANGLE);
162        private Parameter<Length> _opposite, _abs, _plus, _minus;
163        private Parameter _times1, _times2, _times3, _inverse, _divide1, _divide2;
164        private Parameter _sqrt, _root3, _pow3;
165        private Parameter _round, _round2Place;
166        private Parameter _min, _max;
167        private Parameter _sin, _cos, _tan;
168        private Parameter _asin, _acos, _atan, _atan2;
169        
170        
171        @Override
172        public CharSequence getDescription() {
173            return TextBuilder.newInstance().append("Parameter math operations: p1 = ")
174                    .append(p1).append(", p2 = ").append(p2).append(", p3 = ").append(p3)
175                    .append(", K = ").append(K);
176        }
177        
178        @Override
179        public void execute() {
180            _opposite = p1.opposite();
181            _abs = p1.abs();
182            _plus = p1.plus(p2);
183            _minus = p1.minus(p2);
184            _times1 = p1.times(p2);
185            _times2 = p1.times(K);
186            _times3 = p1.times(Parameter.ZERO);
187            _inverse = p1.inverse();
188            _divide1 = p1.divide(p2);
189            _divide2 = p1.divide(K);
190            _sqrt = p2.sqrt();
191            _root3 = p2.root(3);
192            _pow3 = p1.pow(3);
193            _round = p1.round();
194            _round2Place = p1.roundToPlace(-2);
195            _min = p1.min(p2);
196            _max = p1.max(p2);
197            _sin = Parameter.sin(p3);
198            _cos = Parameter.cos(p3);
199            _tan = Parameter.tan(p3);
200            _asin = Parameter.asin((Parameter)p1.divide(p2));
201            _acos = Parameter.acos((Parameter)p1.divide(p2));
202            _atan = Parameter.atan((Parameter)p1.divide(p2));
203            _atan2 = Parameter.atan2(p1,p2);
204        }
205        
206        @Override
207        public void validate() {
208            Parameter expected = Parameter.valueOf(-P1VALUE,unit);
209            TestContext.assertEquals("p1.opposite()", expected, _opposite);
210            expected = Parameter.valueOf(P1VALUE+P2VALUE,unit);
211            TestContext.assertEquals("p1.plus(p2)", expected, _plus);
212            expected = Parameter.valueOf(P1VALUE-P2VALUE,unit);
213            TestContext.assertEquals("p1.minus(p2)", expected, _minus);
214            expected = Parameter.valueOf(P1VALUE*P2VALUE,Parameter.productOf(unit, unit));
215            TestContext.assertEquals("p1.times(p2)", expected, _times1);
216            expected = Parameter.valueOf(P1VALUE*K,unit);
217            TestContext.assertEquals("p1.times(K)", expected, _times2);
218            expected = Parameter.valueOf(P1VALUE*0,unit);
219            TestContext.assertEquals("p1.times(Parameter.ZERO)", expected, _times3);
220            expected = Parameter.valueOf(1./P1VALUE,unit.inverse());
221            TestContext.assertEquals("p1.inverse()", expected, _inverse);
222            expected = Parameter.valueOf(P1VALUE/P2VALUE,Parameter.productOf(unit, unit.inverse()));
223            TestContext.assertEquals("p1.divide(p2)", expected, _divide1);
224            expected = Parameter.valueOf(P1VALUE/K,unit);
225            TestContext.assertEquals("p1.divide(K)", expected, _divide2);
226            expected = Parameter.valueOf(MathLib.abs(P1VALUE),unit);
227            TestContext.assertEquals("p1.abs()", expected, _abs);
228            expected = Parameter.valueOf(MathLib.sqrt(P2VALUE),unit.root(2));
229            TestContext.assertEquals("p2.sqrt()", expected, _sqrt);
230            expected = Parameter.valueOf(MathLib.pow(P2VALUE,1./3),unit.root(3));
231            TestContext.assertEquals("p2.root(3)", expected, _root3);
232            expected = Parameter.valueOf(MathLib.pow(P1VALUE,3),unit.pow(3));
233            TestContext.assertEquals("p1.pow(3)", expected, _pow3);
234            expected = Parameter.valueOf(MathLib.round(P1VALUE),unit);
235            TestContext.assertEquals("p1.round()", expected, _round);
236            expected = Parameter.valueOf(MathTools.roundToPlace(P1VALUE,-2),unit);
237            TestContext.assertEquals("p1.roundToPlace(-2)", expected, _round2Place);
238            TestContext.assertEquals("p1.min(p2)", p1, _min);
239            TestContext.assertEquals("p1.max(p2)", p2, _max);
240            expected = Parameter.valueOf(MathLib.sin(P3VALUE*MathLib.PI/180),Dimensionless.UNIT);
241            TestContext.assertEquals("Parameter.sin(p3)", expected, _sin);
242            expected = Parameter.valueOf(MathLib.cos(P3VALUE*MathLib.PI/180),Dimensionless.UNIT);
243            TestContext.assertEquals("Parameter.cos(p3)", expected, _cos);
244            expected = Parameter.valueOf(MathLib.tan(P3VALUE*MathLib.PI/180),Dimensionless.UNIT);
245            TestContext.assertEquals("Parameter.tan(p3)", expected, _tan);
246            expected = Parameter.valueOf(MathLib.asin(P1VALUE/P2VALUE),Angle.UNIT);
247            TestContext.assertEquals("Parameter.asin((Parameter)p1.divide(p2))", expected, _asin);
248            expected = Parameter.valueOf(MathLib.acos(P1VALUE/P2VALUE),Angle.UNIT);
249            TestContext.assertEquals("Parameter.acos((Parameter)p1.divide(p2))", expected, _acos);
250            expected = Parameter.valueOf(MathLib.atan(P1VALUE/P2VALUE),Angle.UNIT);
251            TestContext.assertEquals("Parameter.atan((Parameter)p1.divide(p2))", expected, _atan);
252            expected = Parameter.valueOf(MathLib.atan2(P1VALUE,P2VALUE),Angle.UNIT);
253            TestContext.assertEquals("Parameter.atan2(p1,p2)", expected, _atan2);
254        }
255        
256    }
257    
258    public static class ParameterLogicalComparisons extends TestCase {
259        private static final Unit unit = NonSI.FOOT;
260        private static final double P1VALUE = 3.14159;
261        private static final double P2VALUE = -42;
262        private final Parameter<Length> p1 = Parameter.valueOf(P1VALUE,unit);
263        private final Parameter<Length> p2 = Parameter.valueOf(P2VALUE,unit);
264        private final Parameter<Length> p3 = Parameter.valueOf(P1VALUE+Parameter.EPS*2,unit);
265        private boolean _equals1, _equals2;
266        private int _compareTo;
267        private boolean _isLessThan, _isGreaterThan, _isLargerThan;
268        private boolean _isApproxEqual, _isApproxZero;
269        private boolean _isNaN, _isInfinite1, _isInfinite2;
270        
271        
272        @Override
273        public CharSequence getDescription() {
274            return TextBuilder.newInstance().append("Parameter logical comparisons: p1 = ")
275                    .append(p1).append(", p2 = ").append(p2).append(", p3 = p1 + ").append(Parameter.EPS);
276        }
277        
278        @Override
279        public void execute() {
280            _equals1 = p1.equals(p2);
281            _equals2 = p1.equals(Parameter.valueOf(P1VALUE,unit));
282            _compareTo = p1.compareTo(p2);
283            _isLessThan = p1.isLessThan(p2);
284            _isGreaterThan = p1.isGreaterThan(p2);
285            _isLargerThan = p2.isLargerThan(p1);
286            _isApproxEqual = p1.isApproxEqual(p3);
287            _isApproxZero = p1.isApproxZero();
288            _isNaN = p1.isNaN();
289            _isInfinite1 = p1.isInfinite();
290            _isInfinite2 = p1.divide(Parameter.ZERO).isInfinite();
291        }
292        
293        @Override
294        public void validate() {
295            TestContext.assertEquals("p1.equals(p2)", false, _equals1);
296            TestContext.assertEquals("p1.equals(p1)", true, _equals2);
297            TestContext.assertEquals("p1.compareTo(p2)", Double.compare(P1VALUE, P2VALUE), _compareTo);
298            TestContext.assertEquals("p1.isLessThan(p2)", P1VALUE<P2VALUE, _isLessThan);
299            TestContext.assertEquals("p1.isGreaterThan(p2)", P1VALUE>P2VALUE, _isGreaterThan);
300            TestContext.assertEquals("p2.isLargerThan(p1)", MathLib.abs(P2VALUE)>MathLib.abs(P1VALUE), _isLargerThan);
301            TestContext.assertEquals("p1.isApproxEqual(p3)",
302                    MathTools.isApproxEqual(P1VALUE, P1VALUE+Parameter.EPS*2), _isApproxEqual);
303            TestContext.assertEquals("p1.isApproxZero()", false, _isApproxZero);
304            TestContext.assertEquals("p1.isNaN()", false, _isNaN);
305            TestContext.assertEquals("p1.isInfinite()", false, _isInfinite1);
306            TestContext.assertEquals("p1.divide(Parameter.ZERO).isInfinite()", true, _isInfinite2);
307        }
308        
309    }
310
311    public static class DCMatrixTests extends TestCase {
312        private final DCMatrix m1 = DCMatrix.valueOf(1,2,3, 4,5,6, 7,8,9);
313        private final DCMatrix m2 = DCMatrix.valueOf(1,0,1, 0,1,0, -1,0,1);
314        private final Float64 p1 = Float64.valueOf(2);
315        private final Vector3D<Length> v1 = Vector3D.valueOf(1, 2, 3, SI.METER);
316                private final Parameter<Angle> psi = Parameter.valueOf(60,javax.measure.unit.NonSI.DEGREE_ANGLE);
317                private final Parameter<Angle> theta = Parameter.ZERO_ANGLE;
318                private final Parameter<Angle> phi = Parameter.ZERO_ANGLE;
319        private final DCMatrix m3 = DCMatrix.getEulerTM(psi, theta, phi);
320        private final Vector3D<Length> v2 = Vector3D.valueOf(1, 1, 1, SI.METER);
321        private DCMatrix _opp, _plus, _minus, _times1, _times2, _inv, _transp;
322        private Float64 _det1, _det2, _coef;
323        private Float64Matrix _ten;
324        private Vector3D<Length> _times3, _times4;
325        private Quaternion _quat;
326        private Float64Vector _row1, _col2, _diag, _vect;
327        
328        @Override
329        public CharSequence getDescription() {
330            return TextBuilder.newInstance().append("DCMatrix");
331        }
332        
333        @Override
334        public void execute() {
335            _row1 = m1.getRow(1);
336            _col2 = m1.getColumn(2);
337            _diag = m1.getDiagonal();
338            _transp = m1.transpose();
339            _vect = m1.vectorization();
340            _opp = m1.opposite();
341            _plus = m1.plus(m2);
342            _minus = m1.minus(m2);
343            _det1 = m1.determinant();
344            _times1 = m1.times(p1);
345            _det2 = m2.determinant();
346            _inv = m2.inverse();
347            _coef = m2.cofactor(0,2);
348            _times2 = m1.times(m2);
349            _ten = m1.tensor(m2);
350            _times3 = m1.times(v1);
351            _times4 = m3.times(v2);
352            _quat = m3.toQuaternion();
353        }
354        
355        @Override
356        public void validate() {
357            Float64Vector expectedF64v = Float64Vector.valueOf(4,5,6);
358            TestContext.assertEquals("m1.getRow(1)", expectedF64v, _row1);
359            expectedF64v = Float64Vector.valueOf(3,6,9);
360            TestContext.assertEquals("m1.getColumn(2)", expectedF64v, _col2);
361            expectedF64v = Float64Vector.valueOf(1,5,9);
362            TestContext.assertEquals("m1.getDiagonal()", expectedF64v, _diag);
363            DCMatrix expectedM = DCMatrix.valueOf(1,4,7, 2,5,8, 3,6,9);
364            TestContext.assertEquals("m1.transpose()", expectedM, _transp);
365            expectedF64v = Float64Vector.valueOf(1,4,7, 2,5,8, 3,6,9);
366            TestContext.assertEquals("m1.vectorization()", expectedF64v, _vect);
367
368            expectedM = DCMatrix.valueOf(-1,-2,-3, -4,-5,-6, -7,-8,-9);
369            TestContext.assertEquals("m1.opposite()", expectedM, _opp);
370            
371            expectedM = DCMatrix.valueOf(2,2,4, 4,6,6, 6,8,10);
372            TestContext.assertEquals("m1.plus(m2)", expectedM, _plus);
373            
374            expectedM = DCMatrix.valueOf(0,2,2, 4,4,6, 8,8,8);
375            TestContext.assertEquals("m1.minus(m2)", expectedM, _minus);
376            
377            Float64 expectedF64 = Float64.valueOf(6.661338147750939E-16);
378            TestContext.assertEquals("m1.determinant()", expectedF64, _det1);
379            
380            expectedM = DCMatrix.valueOf(2,4,6, 8,10,12, 14,16,18);
381            TestContext.assertEquals("m1.times(p1)", expectedM, _times1);
382            
383            expectedF64 = Float64.valueOf(2);
384            TestContext.assertEquals("m2.determinant()", expectedF64, _det2);
385            
386            expectedM = DCMatrix.valueOf(0.5, 0, -0.5, 0, 1, 0, 0.5, 0, 0.5);
387            TestContext.assertEquals("m2.inverse()", expectedM, _inv);
388            
389            expectedF64 = Float64.valueOf(1);
390            TestContext.assertEquals("m2.cofactor(0,2)", expectedF64, _coef);
391            
392            expectedM = DCMatrix.valueOf(-2,2,4, -2,5,10, -2,8,16);
393            TestContext.assertEquals("m1.times(m2)", expectedM, _times2);
394            
395            Float64Vector row1 = Float64Vector.valueOf(1,0,1,2,0,2,3,0,3);
396            Float64Vector row2 = Float64Vector.valueOf(0,1,0,0,2,0,0,3,0);
397            Float64Vector row3 = Float64Vector.valueOf(-1,0,1,-2,0,2,-3,0,3);
398            Float64Vector row4 = Float64Vector.valueOf(4,0,4,5,0,5,6,0,6);
399            Float64Vector row5 = Float64Vector.valueOf(0,4,0,0,5,0,0,6,0);
400            Float64Vector row6 = Float64Vector.valueOf(-4,0,4,-5,0,5,-6,0,6);
401            Float64Vector row7 = Float64Vector.valueOf(7,0,7,8,0,8,9,0,9);
402            Float64Vector row8 = Float64Vector.valueOf(0,7,0,0,8,0,0,9,0);
403            Float64Vector row9 = Float64Vector.valueOf(-7,0,7,-8,0,8,-9,0,9);
404            Float64Matrix expectedM64 = Float64Matrix.valueOf(row1,row2,row3,row4,row5,row6,row7,row8,row9);
405            TestContext.assertEquals("m1.tensor(m2)", expectedM64, _ten);
406
407            Vector3D expectedV = Vector3D.valueOf(14,32,50,SI.METER);
408            TestContext.assertEquals("m2.cofactor(0,2)", expectedV, _times3);
409            
410            expectedV = Vector3D.valueOf(-0.3660254037844385,1.3660254037844388,1,SI.METER);
411            TestContext.assertEquals("m3.times(v2)", expectedV, _times4);
412            
413            Quaternion expectedQ = Quaternion.valueOf(0, 0, 0.5, MathLib.sin(60*MathLib.PI/180));
414            TestContext.assertEquals("m3.toQuaternion()", expectedQ, _quat);
415        }
416    }
417
418    public static class QuaternionTests extends TestCase {
419                private final Parameter<Angle> psi = Parameter.valueOf(60,javax.measure.unit.NonSI.DEGREE_ANGLE);
420                private final Parameter<Angle> theta = Parameter.ZERO_ANGLE;
421                private final Parameter<Angle> theta2 = Parameter.valueOf(30,NonSI.DEGREE_ANGLE);
422                private final Parameter<Angle> phi = Parameter.ZERO_ANGLE;
423        private final DCMatrix m1 = DCMatrix.getEulerTM(psi, theta, phi);
424        private final Quaternion q1 = Quaternion.valueOf(m1);
425        private final DCMatrix m2 = DCMatrix.getEulerTM(psi, theta2, phi);
426        private final Quaternion q3 = Quaternion.valueOf(Vector3D.UNIT_Y, theta2);
427        private final Vector3D<Length> v1 = Vector3D.valueOf(1, 0, 0, SI.METER);
428        private Float64 _norm, _s1;
429        private Vector3D _v1, _v2, _v3;
430        private Quaternion _opp, _conj, _inv, _q2, _q4, _Lq1tq3, _plus, _minus, _unit;
431        private DCMatrix _dcm;
432        
433        @Override
434        public CharSequence getDescription() {
435            return TextBuilder.newInstance().append("Quaternion");
436        }
437        
438        @Override
439        public void execute() {
440            _opp = q1.opposite();
441            _norm = q1.norm();
442            _v1 = q1.getVector();
443            _s1 = q1.getScalar();
444            _conj = q1.conjugate();
445            _inv = q1.inverse();
446            _dcm = q1.toDCM();
447            _v2 = q1.transform(v1);
448            _q2 = Quaternion.valueOf(Vector3D.UNIT_Z, psi);
449            _q4 = q1.times(q3);
450            _v3 = _q4.transform(v1);
451            _Lq1tq3 = Quaternion.valueOf(q1.toLeftMatrix().times(q3.toFloat64Vector()));
452            _plus = q1.plus(q3);
453            _minus = q1.minus(q3);
454            _unit = q3.toUnit();
455        }
456        
457        @Override
458        public void validate() {
459            Float64 expectedF64 = Float64.valueOf(0.99999999999999989);
460            TestContext.assertEquals("q1.norm()", expectedF64, _norm);
461            
462            Vector3D expectedV3D = Vector3D.valueOf(0,0,0.5,Dimensionless.UNIT);
463            TestContext.assertEquals("q1.getVector()", expectedV3D, _v1);
464            
465            expectedF64 = Float64.valueOf(MathLib.sin(60*MathLib.PI/180));
466            TestContext.assertEquals("q1.getScalar()", expectedF64, _s1);
467            
468            Quaternion expectedQ = Quaternion.valueOf(0,0,-0.5,-MathLib.sin(60*MathLib.PI/180));
469            TestContext.assertEquals("q1.opposite()", expectedQ, _opp);
470            
471            expectedQ = Quaternion.valueOf(0,0,-0.5,MathLib.sin(60*MathLib.PI/180));
472            TestContext.assertEquals("q1.conjugate()", expectedQ, _conj);
473            
474            expectedQ = Quaternion.valueOf(0,0,-0.5,MathLib.sin(60*MathLib.PI/180));
475            TestContext.assertEquals("q1.inverse()", true, expectedQ.isApproxEqual(_inv));
476            
477            DCMatrix expectedDCM = m1;
478            TestContext.assertEquals("q1.toDCM()", true, expectedDCM.isApproxEqual(_dcm));
479            
480            expectedV3D = Vector3D.valueOf(0.5,MathLib.sin(60*MathLib.PI/180),0,SI.METER);
481            TestContext.assertEquals("q1.transform(v1)", true, expectedV3D.isApproxEqual(_v2));
482            
483            TestContext.assertEquals("Quaternion.valueOf(Vector3D.UNIT_Z, psi)", true, q1.isApproxEqual(_q2));
484            
485            expectedQ = Quaternion.valueOf(-0.12940952255126037,0.22414386804201336,0.48296291314453416,0.8365163037378078);
486            TestContext.assertEquals("q1.times(q3)", true, expectedQ.isApproxEqual(_q4));
487            
488            expectedV3D = m2.times(v1);
489            TestContext.assertEquals("q4.transform(v1)", true, expectedV3D.isApproxEqual(_v3));
490            
491            TestContext.assertEquals("q1.toLeftMatrix().times(q3.toFloat64Vector())", true, expectedQ.isApproxEqual(_Lq1tq3));
492            
493            expectedQ = Quaternion.valueOf(0,0.25881904510252074,0.5,MathLib.sin(60*MathLib.PI/180)+0.9659258262890683);
494            TestContext.assertEquals("q1.plus(q3)", true, expectedQ.isApproxEqual(_plus));
495            
496            expectedQ = Quaternion.valueOf(0,-0.25881904510252074,0.5,MathLib.sin(60*MathLib.PI/180)-0.9659258262890683);
497            TestContext.assertEquals("q1.minus(q3)", true, expectedQ.isApproxEqual(_minus));
498            
499            expectedQ = Quaternion.valueOf(0.0, 0.25881904510252074, 0.0, 0.9659258262890683);
500            TestContext.assertEquals("q3.toUnit()", true, expectedQ.isApproxEqual(_unit));
501            
502        }
503    }
504}