1 package org.djunits.value;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.fail;
5
6 import java.lang.reflect.Array;
7 import java.lang.reflect.Constructor;
8 import java.lang.reflect.Field;
9 import java.lang.reflect.InvocationTargetException;
10 import java.lang.reflect.Method;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.List;
14 import java.util.SortedMap;
15 import java.util.TreeMap;
16
17 import org.djunits.unit.UNITS;
18 import org.djunits.unit.Unit;
19 import org.djunits.unit.unitsystem.UnitSystem;
20 import org.djunits.util.ClassUtil;
21 import org.djunits.value.vdouble.scalar.AbstractDoubleScalar;
22 import org.djunits.value.vdouble.scalar.Area;
23 import org.djunits.value.vdouble.scalar.DoubleScalar;
24 import org.djunits.value.vdouble.scalar.Length;
25 import org.djunits.value.vdouble.vector.AbstractDoubleVector;
26 import org.djunits.value.vdouble.vector.DoubleVectorInterface;
27 import org.djunits.value.vdouble.vector.MutableDoubleVectorInterface;
28 import org.djunits.value.vfloat.scalar.AbstractFloatScalar;
29 import org.djunits.value.vfloat.scalar.FloatScalar;
30 import org.djunits.value.vfloat.vector.AbstractFloatVector;
31 import org.djunits.value.vfloat.vector.FloatVectorInterface;
32 import org.djunits.value.vfloat.vector.MutableFloatVectorInterface;
33 import org.junit.Assert;
34 import org.junit.Test;
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class VectorOperationsTest<TypedDoubleVectorAbs> implements UNITS
49 {
50
51 public static final String[] CLASSNAMES_ABS = new String[] { "AbsoluteTemperature", "Direction", "Position", "Time" };
52
53
54 public static final String[] CLASSNAMES_ABS_REL = new String[] { "Temperature", "Angle", "Length", "Duration" };
55
56
57 public static final String[] CLASSNAMES_REL = new String[] { "Angle", "Acceleration", "AngleSolid", "Area", "Density",
58 "Dimensionless", "Duration", "ElectricalCharge", "ElectricalCurrent", "ElectricalPotential", "ElectricalResistance",
59 "Energy", "FlowMass", "FlowVolume", "Force", "Frequency", "Length", "LinearDensity", "Mass", "Power", "Pressure",
60 "Speed", "Temperature", "Torque", "Volume" };
61
62
63 public static final String[] CLASSNAMES_MONEY = new String[] { "Money", "MoneyPerArea", "MoneyPerEnergy", "MoneyPerLength",
64 "MoneyPerMass", "MoneyPerDuration", "MoneyPerVolume" };
65
66
67
68
69
70
71
72
73
74
75
76
77
78 @SuppressWarnings("static-method")
79 @Test
80 public final void vectorOperationsTest()
81 throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException,
82 NoSuchFieldException, SecurityException, IllegalArgumentException, ClassNotFoundException, ValueException
83 {
84 doubleOrFloatScalarOperationsTest(true);
85 doubleOrFloatScalarOperationsTest(false);
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 private void doubleOrFloatScalarOperationsTest(final boolean doubleType)
102 throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException,
103 NoSuchFieldException, SecurityException, IllegalArgumentException, ClassNotFoundException, ValueException
104 {
105 final String upperVectorType = "Vector";
106 final String floatPrefix = doubleType ? "" : "Float";
107 String doubleOrFloat = doubleType ? "double" : "float";
108 for (boolean mutable : new boolean[] { false, true })
109 {
110 for (StorageType storageType : StorageType.values())
111 {
112
113 for (int i = 0; i < CLASSNAMES_ABS.length; i++)
114 {
115 String vectorNameAbs = CLASSNAMES_ABS[i];
116 Class<?> vectorClassAbs = null;
117 String classNameAbs = "org.djunits.value.v" + doubleOrFloat + ".vector." + (mutable ? "Mutable" : "")
118 + floatPrefix + vectorNameAbs + upperVectorType;
119 System.out.println("Looking up class " + classNameAbs);
120 vectorClassAbs = Class.forName(classNameAbs);
121 Class<?> vectorClassRel = null;
122
123 String vectorNameRel = CLASSNAMES_ABS_REL[i];
124 String classNameRel = "org.djunits.value.v" + doubleOrFloat + ".vector." + (mutable ? "Mutable" : "")
125 + floatPrefix + vectorNameRel + upperVectorType;
126 vectorClassRel = Class.forName(classNameRel);
127
128 testMethods(vectorClassAbs, true, doubleType, storageType, mutable);
129 testMethods(vectorClassRel, false, doubleType, storageType, mutable);
130
131
132 }
133
134 for (String vectorName : CLASSNAMES_REL)
135 {
136 String vectorClassName = (doubleType ? "" : "Float") + vectorName;
137 String fullClassName = "org.djunits.value.v" + doubleOrFloat + ".vector." + (mutable ? "Mutable" : "")
138 + vectorClassName + "Vector";
139 Class<?> vectorClass = null;
140 vectorClass = Class.forName(fullClassName);
141 testMethods(vectorClass, false, doubleType, storageType, mutable);
142 }
143
144 for (String vectorName : CLASSNAMES_MONEY)
145 {
146 String vectorClassName = doubleType ? vectorName : "Float" + vectorName;
147 String fullClassName = "org.djunits.value.v" + doubleOrFloat + ".vector." + (mutable ? "Mutable" : "")
148 + vectorClassName + "Vector";
149 Class<?> vectorClass = null;
150 vectorClass = Class.forName(fullClassName);
151 testMethods(vectorClass, false, doubleType, storageType, mutable);
152 }
153 }
154 }
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 private void testMethods(final Class<?> vectorClassAbsRel, final boolean isAbs, final boolean doubleType,
174 final StorageType storageType, final boolean mutable) throws NoSuchMethodException, InstantiationException,
175 IllegalAccessException, InvocationTargetException, NoSuchFieldException, ClassNotFoundException, ValueException
176 {
177
178 for (Method method : vectorClassAbsRel.getMethods())
179 {
180
181 if (method.getName().equals("multiplyBy"))
182 {
183 testMultiplyByOrDivideByMethod(vectorClassAbsRel, method, true, doubleType, isAbs, storageType);
184 }
185 else if (method.getName().equals("divideBy"))
186 {
187 testMultiplyByOrDivideByMethod(vectorClassAbsRel, method, false, doubleType, isAbs, storageType);
188 }
189 }
190 testConstructors(vectorClassAbsRel, isAbs, doubleType, mutable, storageType);
191 testGet(vectorClassAbsRel, isAbs, doubleType, mutable, storageType);
192 testUnaryMethods(vectorClassAbsRel, isAbs, doubleType, mutable, storageType);
193 testInterpolateMethod(vectorClassAbsRel, isAbs, doubleType, storageType);
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214 private void testMultiplyByOrDivideByMethod(final Class<?> vectorClass, final Method method, final boolean multiply,
215 final boolean doubleType, final boolean abs, final StorageType storageType)
216 throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException,
217 NoSuchFieldException, ClassNotFoundException, SecurityException, IllegalArgumentException, ValueException
218 {
219
220 Class<?>[] parTypes = method.getParameterTypes();
221 if (parTypes.length != 1)
222 {
223 fail("DoubleScalar class " + vectorClass.getName() + "." + method.getName() + "() has " + parTypes.length
224 + " parameters, <> 1");
225 }
226 Class<?> parameterClass = parTypes[0];
227 if (parameterClass.toString().equals("double") || parameterClass.toString().equals("float"))
228 {
229
230 return;
231 }
232
233
234
235 if (!vectorClass.isAssignableFrom(parameterClass))
236 {
237 return;
238 }
239
240 Class<?> returnClass = method.getReturnType();
241 if (!vectorClass.isAssignableFrom(returnClass))
242 {
243 Assert.fail("DoubleScalar class " + vectorClass.getName()
244 + ".multiplyBy() has return type with incompatible class: " + returnClass.getName());
245 }
246
247
248 String returnSI = getCoefficients(getUnitClass(returnClass));
249 String scalarSI = getCoefficients(getUnitClass(vectorClass));
250 String paramSI = getCoefficients(getUnitClass(parameterClass));
251
252 System.out.println(vectorClass.getName().replaceFirst("org.djunits.value.vdouble.scalar.", "") + "."
253 + (multiply ? "multiplyBy" : "divideBy") + "("
254 + parameterClass.getName().replaceFirst("org.djunits.value.vdouble.scalar.", "") + ") => "
255 + returnClass.getName().replaceFirst("org.djunits.value.vdouble.scalar.", "") + ": " + scalarSI
256 + (multiply ? " * " : " : ") + paramSI + " => " + returnSI);
257
258 Constructor<?> constructor = vectorClass.getConstructor(double.class, getUnitClass(vectorClass));
259 if (doubleType)
260 {
261 DoubleScalar.Rel<?> left =
262 (DoubleScalar.Rel<?>) constructor.newInstance(123d, getSIUnitInstance(getUnitClass(vectorClass)));
263
264 constructor = parameterClass.getConstructor(double.class, getUnitClass(parameterClass));
265 DoubleScalar.Rel<?> right =
266 (DoubleScalar.Rel<?>) constructor.newInstance(456d, getSIUnitInstance(getUnitClass(parameterClass)));
267
268 double expectedValue = multiply ? 123d * 456 : 123d / 456;
269
270 if (multiply)
271 {
272 Method multiplyMethod = vectorClass.getDeclaredMethod("multiplyBy", new Class[] { parameterClass });
273 Object result = multiplyMethod.invoke(left, right);
274 double resultSI = ((DoubleScalar.Rel<?>) result).si;
275 assertEquals("Result of operation", expectedValue, resultSI, 0.01);
276 }
277 else
278 {
279 Method divideMethod = vectorClass.getDeclaredMethod("divideBy", new Class[] { parameterClass });
280 Object result = divideMethod.invoke(left, right);
281 double resultSI = ((DoubleScalar.Rel<?>) result).si;
282 assertEquals("Result of operation", expectedValue, resultSI, 0.01);
283 }
284 DoubleScalar.Rel<?> result = multiply ? DoubleScalar.multiply(left, right) : DoubleScalar.divide(left, right);
285
286 String resultCoefficients = result.getUnit().getSICoefficientsString();
287 assertEquals("SI coefficients of result should match expected SI coefficients", resultCoefficients, returnSI);
288 }
289 else
290 {
291 FloatScalar.Rel<?> left =
292 (FloatScalar.Rel<?>) constructor.newInstance(123f, getSIUnitInstance(getUnitClass(vectorClass)));
293
294 constructor = parameterClass.getConstructor(double.class, getUnitClass(parameterClass));
295 FloatScalar.Rel<?> right =
296 (FloatScalar.Rel<?>) constructor.newInstance(456f, getSIUnitInstance(getUnitClass(parameterClass)));
297
298 float expectedValue = multiply ? 123f * 456 : 123f / 456;
299
300 if (multiply)
301 {
302 Method multiplyMethod = vectorClass.getDeclaredMethod("multiplyBy", new Class[] { parameterClass });
303 Object result = multiplyMethod.invoke(left, right);
304 double resultSI = ((FloatScalar.Rel<?>) result).si;
305 assertEquals("Result of operation", expectedValue, resultSI, 0.01);
306 }
307 else
308 {
309 Method divideMethod = vectorClass.getDeclaredMethod("divideBy", new Class[] { parameterClass });
310 Object result = divideMethod.invoke(left, right);
311 float resultSI = ((FloatScalar.Rel<?>) result).si;
312 assertEquals("Result of operation", expectedValue, resultSI, 0.01);
313 }
314 FloatScalar.Rel<?> result = multiply ? FloatScalar.multiply(left, right) : FloatScalar.divide(left, right);
315
316 String resultCoefficients = result.getUnit().getSICoefficientsString();
317 assertEquals("SI coefficients of result should match expected SI coefficients", resultCoefficients, returnSI);
318 }
319 }
320
321
322
323
324
325
326
327
328 private String getCoefficients(final Class<?> clas) throws IllegalAccessException, NoSuchFieldException
329 {
330 if (clas.getName().contains("Money"))
331 {
332
333 for (Field field : clas.getDeclaredFields())
334 {
335 if (field.getType().equals(clas))
336 {
337 return ((Unit<?>) field.get(clas)).getSICoefficientsString();
338 }
339 }
340 return "1";
341 }
342 Field si = clas.getField("SI");
343 Unit<?> u = ((Unit<?>) si.get(clas));
344 String r = u.getSICoefficientsString();
345 return r;
346
347 }
348
349
350
351
352
353
354
355
356 private Unit<?> getSIUnitInstance(final Class<?> clas) throws NoSuchFieldException, IllegalAccessException
357 {
358 if (clas.getName().contains("Money"))
359 {
360
361 for (Field field : clas.getDeclaredFields())
362 {
363 if (field.getType().equals(clas))
364 {
365 return ((Unit<?>) field.get(clas));
366 }
367 }
368 return null;
369 }
370
371 Field si = null;
372 try
373 {
374 si = clas.getField("SI");
375 }
376 catch (NoSuchFieldException nsfe)
377 {
378 si = clas.getField("BASE");
379 }
380 return ((Unit<?>) si.get(clas));
381 }
382
383
384
385
386
387
388 private Class<?> getUnitClass(final Class<?> vectorClass)
389 {
390 Constructor<?>[] constructors = vectorClass.getConstructors();
391 for (Constructor<?> constructor : constructors)
392 {
393 Class<?>[] parTypes = constructor.getParameterTypes();
394
395
396
397
398
399
400
401
402 if (parTypes.length >= 2 && Unit.class.isAssignableFrom(parTypes[1]))
403 {
404 return parTypes[1];
405 }
406 }
407 Assert.fail("Could not find constructor with a unit as 2nd argument for Vector class " + vectorClass.getName());
408 return null;
409 }
410
411
412
413
414
415
416
417
418
419
420
421 private void verifyAbsRelPrecisionAndValues(final boolean abs, final boolean doubleType, final StorageType storageType,
422 final Object got, final Object expected, final double precision) throws ValueException
423 {
424 int size = doubleType ? ((double[]) expected).length : ((float[]) expected).length;
425 int refSize = doubleType ? ((double[]) expected).length : ((float[]) expected).length;
426 assertEquals("size of resulting array", refSize, size);
427 for (int i = 0; i < size; i++)
428 {
429 double result = verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, got, i);
430 assertEquals("value check", doubleType ? ((double[]) expected)[i] : ((float[]) expected)[i], result, precision);
431 }
432 }
433
434
435
436
437
438
439
440
441
442
443
444 private double verifyAbsRelPrecisionAndExtractSI(final boolean abs, final boolean doubleType, final StorageType storageType,
445 final Object o, final int index) throws ValueException
446 {
447 double result = Double.NaN;
448 if (doubleType)
449 {
450 if (!(o instanceof DoubleVectorInterface))
451 {
452 fail("object is not a DoubleVector");
453 }
454 AbstractDoubleVector<?, ?> dv = (AbstractDoubleVector<?, ?>) o;
455 result = dv.getSI(index);
456 assertEquals("StorageType", storageType, dv.getStorageType());
457 }
458 else
459 {
460 if (!(o instanceof FloatVectorInterface))
461 {
462 fail("object is not a FloatVector");
463 }
464 AbstractFloatVector<?, ?> fv = (AbstractFloatVector<?, ?>) o;
465 result = fv.getSI(index);
466 assertEquals("StorageType", storageType, fv.getStorageType());
467 }
468 if (o instanceof Absolute)
469 {
470 if (!abs)
471 {
472 fail("Result should have been Absolute");
473 }
474 }
475 else if (o instanceof Relative)
476 {
477 if (abs)
478 {
479 fail("Result should have been Relative");
480 }
481 }
482 else
483 {
484 fail("Result is neither Absolute, nor Relative");
485 }
486 return result;
487 }
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503 private void testConstructors(final Class<?> vectorClass, final boolean abs, final boolean doubleType,
504 final boolean mutable, final StorageType storageType) throws NoSuchMethodException, InstantiationException,
505 IllegalAccessException, InvocationTargetException, NoSuchFieldException, ClassNotFoundException, ValueException
506 {
507 double[] doubleValue = { 1.23456, 2.34567, 3.45678 };
508 float[] floatValue = { 1.23456f, 2.34567f, 3.45678f };
509 Object value = doubleType ? doubleValue : floatValue;
510 findAndTestConstructor(vectorClass, new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType },
511 abs, doubleType, storageType, value);
512
513 String scalarClassName = vectorClass.getName();
514
515 scalarClassName = scalarClassName.replaceFirst("Vector", "");
516
517 scalarClassName = scalarClassName.replaceFirst("vector", "scalar");
518
519 scalarClassName = scalarClassName.replaceFirst("Mutable", "");
520
521 Class<?> scalarClassAbsRel = Class.forName(scalarClassName);
522
523 if (doubleType)
524 {
525 List<Double> list = new ArrayList<Double>();
526 for (int i = 0; i < doubleValue.length; i++)
527 {
528 list.add(doubleValue[i]);
529 }
530 findAndTestConstructor(vectorClass,
531 new Object[] { list, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, abs, doubleType,
532 storageType, value);
533
534 Constructor<?> constructor =
535 scalarClassAbsRel.getConstructor(new Class<?>[] { double.class, getUnitClass(vectorClass) });
536 List<Object> objectList = new ArrayList<Object>();
537 for (Double d : list)
538 {
539 objectList.add(constructor.newInstance(d, getSIUnitInstance(getUnitClass(vectorClass))));
540 }
541 findAndTestConstructor(vectorClass, new Object[] { objectList, storageType }, abs, doubleType, storageType, value);
542
543 Object[] objectArray = (Object[]) Array.newInstance(scalarClassAbsRel, objectList.size());
544 for (int i = 0; i < objectList.size(); i++)
545 {
546 objectArray[i] = objectList.get(i);
547 }
548 findAndTestConstructor(vectorClass, new Object[] { objectArray, storageType }, abs, doubleType, storageType, value);
549 SortedMap<Integer, Object> map = new TreeMap<Integer, Object>();
550 for (int i = 0; i < objectList.size(); i++)
551 {
552 map.put(i, objectList.get(i));
553 }
554
555 findAndTestConstructor(vectorClass, new Object[] { map, objectList.size(), storageType }, abs, doubleType,
556 storageType, value);
557 map.clear();
558 for (int i = 0; i < doubleValue.length; i++)
559 {
560 map.put(i, doubleValue[i]);
561 }
562 findAndTestConstructor(vectorClass,
563 new Object[] { map, getSIUnitInstance(getUnitClass(vectorClass)), doubleValue.length, storageType }, abs,
564 doubleType, storageType, value);
565 }
566 else
567 {
568 List<Float> list = new ArrayList<Float>();
569 for (int i = 0; i < floatValue.length; i++)
570 {
571 list.add(floatValue[i]);
572 }
573 findAndTestConstructor(vectorClass,
574 new Object[] { list, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, abs, doubleType,
575 storageType, value);
576
577 Constructor<?> constructor =
578 scalarClassAbsRel.getConstructor(new Class<?>[] { double.class, getUnitClass(vectorClass) });
579 List<Object> objectList = new ArrayList<Object>();
580 for (Float f : list)
581 {
582 objectList.add(constructor.newInstance(f, getSIUnitInstance(getUnitClass(vectorClass))));
583 }
584 findAndTestConstructor(vectorClass, new Object[] { objectList, storageType }, abs, doubleType, storageType, value);
585
586 Object[] objectArray = (Object[]) Array.newInstance(scalarClassAbsRel, objectList.size());
587 for (int i = 0; i < objectList.size(); i++)
588 {
589 objectArray[i] = objectList.get(i);
590 }
591 findAndTestConstructor(vectorClass, new Object[] { objectArray, storageType }, abs, doubleType, storageType, value);
592 SortedMap<Integer, Object> map = new TreeMap<Integer, Object>();
593 for (int i = 0; i < objectList.size(); i++)
594 {
595 map.put(i, objectList.get(i));
596 }
597
598 findAndTestConstructor(vectorClass, new Object[] { map, objectList.size(), storageType }, abs, doubleType,
599 storageType, value);
600 map.clear();
601 for (int i = 0; i < floatValue.length; i++)
602 {
603 map.put(i, floatValue[i]);
604 }
605 findAndTestConstructor(vectorClass,
606 new Object[] { map, getSIUnitInstance(getUnitClass(vectorClass)), floatValue.length, storageType }, abs,
607 doubleType, storageType, value);
608 }
609 }
610
611
612
613
614
615
616 private String paramsToString(final Class<?>[] params)
617 {
618 StringBuilder result = new StringBuilder();
619 result.append("(");
620 String separator = "";
621 for (Class<?> parType : params)
622 {
623 result.append(separator + parType);
624 separator = ", ";
625 }
626 result.append(")");
627 return result.toString();
628 }
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644 private Object findAndExecuteConstructor(final Class<?> vectorClass, final Object[] args, final boolean doubleType)
645 throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException,
646 IllegalArgumentException, InvocationTargetException, ValueException
647 {
648 Class<?>[] parameterTypes = new Class<?>[args.length];
649 for (int i = 0; i < args.length; i++)
650 {
651 Class<?> c = args[i].getClass();
652 if (c.isAssignableFrom(double[].class))
653 {
654 c = double[].class;
655 }
656 else if (c.isAssignableFrom(float[].class))
657 {
658 c = float[].class;
659 }
660 parameterTypes[i] = c;
661
662 }
663 Constructor<?> constructor = null;
664 for (Constructor<?> c : vectorClass.getConstructors())
665 {
666
667 Class<?>[] parTypes = c.getParameterTypes();
668 boolean compatible = parTypes.length == args.length;
669 for (int i = 0; i < parTypes.length; i++)
670 {
671 Class<?> parType = parTypes[i];
672 if (compatible && !parType.isAssignableFrom(parameterTypes[i])
673 && (!(parType == int.class && parameterTypes[i] == Integer.class)))
674 {
675 compatible = false;
676 }
677 }
678 if (compatible)
679 {
680
681 constructor = c;
682 }
683 }
684
685 if (null == constructor)
686 {
687 System.out.println("No suitable constructor for " + vectorClass + ":");
688 for (int i = 0; i < args.length; i++)
689 {
690 System.out.println("\tparameter type[" + i + "] is " + args[i].getClass());
691 }
692 fail("Cannot find suitable constructor");
693 }
694 return constructor.newInstance(args);
695 }
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714 private void findAndTestConstructor(final Class<?> vectorClass, final Object[] args, final boolean abs,
715 final boolean doubleType, final StorageType expectedStorageType, final Object expectedResult)
716 throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException,
717 IllegalArgumentException, InvocationTargetException, ValueException
718 {
719 verifyAbsRelPrecisionAndValues(abs, doubleType, expectedStorageType,
720 findAndExecuteConstructor(vectorClass, args, doubleType), expectedResult, 0.0001);
721 }
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738 private void testGet(final Class<?> vectorClass, final boolean abs, final boolean doubleType, final boolean mutable,
739 final StorageType storageType) throws NoSuchMethodException, InstantiationException, IllegalAccessException,
740 InvocationTargetException, NoSuchFieldException, ClassNotFoundException, ValueException
741 {
742 double[] doubleValue = { 1.23456, 2.34567, 3.45678 };
743 float[] floatValue = { 1.23456f, 2.34567f, 3.45678f };
744 Object value = doubleType ? doubleValue : floatValue;
745 Object vector = findAndExecuteConstructor(vectorClass,
746 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
747 if (doubleType)
748 {
749 AbstractDoubleVector<?, ?> dv = (AbstractDoubleVector<?, ?>) vector;
750 for (int i = 0; i < doubleValue.length; i++)
751 {
752 AbstractDoubleScalar<?, ?> ds = dv.get(i);
753 double got = ds.getSI();
754 assertEquals("get returns expected value", doubleValue[i], got, 0.0001);
755 }
756 }
757 else
758 {
759 AbstractFloatVector<?, ?> fv = (AbstractFloatVector<?, ?>) vector;
760 for (int i = 0; i < doubleValue.length; i++)
761 {
762 AbstractFloatScalar<?, ?> fs = fv.get(i);
763 float got = fs.getSI();
764 assertEquals("get returns expected value", doubleValue[i], got, 0.0001);
765 }
766 }
767 }
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783 private void testUnaryMethods(final Class<?> vectorClass, final boolean abs, final boolean doubleType,
784 final boolean mutable, final StorageType storageType) throws NoSuchMethodException, InstantiationException,
785 IllegalAccessException, InvocationTargetException, NoSuchFieldException, ClassNotFoundException, ValueException
786 {
787 double[] doubleValue = { 1.23456, -2.34567, 3.45678 };
788 float[] floatValue = { 1.23456f, -2.34567f, 3.45678f };
789 Object value = doubleType ? doubleValue : floatValue;
790 Object left = findAndExecuteConstructor(vectorClass,
791 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
792 Object result;
793 if (doubleType)
794 {
795 result = ((DoubleVectorInterface<?>) left).toSparse();
796 verifyAbsRelPrecisionAndValues(abs, doubleType, StorageType.SPARSE, result, value, 0.0001);
797 result = ((DoubleVectorInterface<?>) left).toDense();
798 verifyAbsRelPrecisionAndValues(abs, doubleType, StorageType.DENSE, result, value, 0.0001);
799 result = ((DoubleVectorInterface<?>) left).mutable();
800 verifyAbsRelPrecisionAndValues(abs, doubleType, storageType, result, value, 0.0001);
801 result = ((MutableDoubleVectorInterface<?>) result).immutable();
802 verifyAbsRelPrecisionAndValues(abs, doubleType, storageType, result, value, 0.0001);
803 if (abs)
804 {
805 double[] thirdValue = new double[doubleValue.length];
806 double[] twoThirdValue = new double[doubleValue.length];
807 for (int i = 0; i < thirdValue.length; i++)
808 {
809 thirdValue[i] = doubleValue[i] / 3;
810 twoThirdValue[i] = 2 * thirdValue[i];
811 }
812
813
814
815
816
817
818
819
820
821
822
823
824
825 }
826 }
827 else
828 {
829 result = ((FloatVectorInterface<?>) left).toSparse();
830 verifyAbsRelPrecisionAndValues(abs, doubleType, StorageType.SPARSE, result, value, 0.0001);
831 result = ((FloatVectorInterface<?>) left).toDense();
832 verifyAbsRelPrecisionAndValues(abs, doubleType, StorageType.DENSE, result, value, 0.0001);
833 result = ((FloatVectorInterface<?>) left).mutable();
834 verifyAbsRelPrecisionAndValues(abs, doubleType, storageType, result, value, 0.0001);
835 result = ((MutableFloatVectorInterface<?>) result).immutable();
836 verifyAbsRelPrecisionAndValues(abs, doubleType, storageType, result, value, 0.0001);
837 if (abs)
838 {
839 double[] thirdValue = new double[floatValue.length];
840 double[] twoThirdValue = new double[floatValue.length];
841 for (int i = 0; i < thirdValue.length; i++)
842 {
843 thirdValue[i] = floatValue[i] / 3;
844 twoThirdValue[i] = 2 * thirdValue[i];
845 }
846
847
848
849
850
851
852
853
854
855
856
857
858
859 }
860 }
861
862 if (mutable)
863 {
864 double doubleDifference = 42.42;
865 float floatDifference = 42.42f;
866 Class<?> argumentClass = doubleType ? double.class : float.class;
867 Method incrementBy = ClassUtil.resolveMethod(vectorClass, "incrementBy", new Class<?>[] { argumentClass });
868 incrementBy = ClassUtil.resolveMethod(vectorClass, "incrementBy", new Class<?>[] { argumentClass });
869 incrementBy.setAccessible(true);
870
871
872
873 if (doubleType)
874 {
875 result = incrementBy.invoke(left, new Object[] { doubleDifference });
876 }
877 else
878 {
879 result = incrementBy.invoke(left, new Object[] { floatDifference });
880 }
881 for (int i = 0; i < doubleValue.length; i++)
882 {
883 double resultElement = verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i);
884 assertEquals("value check result",
885 doubleType ? (doubleValue[i] + doubleDifference) : (floatValue[i] + floatDifference), resultElement,
886 0.00001);
887
888 double originalElement = verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i);
889 assertEquals("value check original",
890 doubleType ? (doubleValue[i] + doubleDifference) : (floatValue[i] + floatDifference), originalElement,
891 0.00001);
892 }
893 left = findAndExecuteConstructor(vectorClass,
894 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
895 Method decrementBy = ClassUtil.resolveMethod(vectorClass, "decrementBy", new Class<?>[] { argumentClass });
896 decrementBy.setAccessible(true);
897 if (doubleType)
898 {
899 result = decrementBy.invoke(left, new Object[] { doubleDifference });
900 }
901 else
902 {
903 result = decrementBy.invoke(left, new Object[] { floatDifference });
904 }
905 for (int i = 0; i < doubleValue.length; i++)
906 {
907 double resultElement = verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i);
908 assertEquals("value check",
909 doubleType ? (doubleValue[i] - doubleDifference) : (floatValue[i] - floatDifference), resultElement,
910 0.00001);
911
912 double originalElement = verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i);
913 assertEquals("value check original",
914 doubleType ? (doubleValue[i] - doubleDifference) : (floatValue[i] - floatDifference), originalElement,
915 0.00001);
916 }
917
918 left = findAndExecuteConstructor(vectorClass,
919 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
920 Method mathMethod = ClassUtil.resolveMethod(vectorClass, "ceil", new Class[] {});
921 mathMethod.setAccessible(true);
922 result = mathMethod.invoke(left);
923 for (int i = 0; i < doubleValue.length; i++)
924 {
925 assertEquals("Result of operation",
926 doubleType ? Math.ceil(doubleValue[i]) : ((float) Math.ceil(doubleValue[i])),
927 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
928
929 assertEquals("Result of operation",
930 doubleType ? Math.ceil(doubleValue[i]) : ((float) Math.ceil(doubleValue[i])),
931 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
932 }
933
934 left = findAndExecuteConstructor(vectorClass,
935 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
936 mathMethod = ClassUtil.resolveMethod(vectorClass, "floor", new Class[] {});
937 mathMethod.setAccessible(true);
938 result = mathMethod.invoke(left);
939 for (int i = 0; i < doubleValue.length; i++)
940 {
941 assertEquals("Result of operation",
942 doubleType ? Math.floor(doubleValue[i]) : ((float) Math.floor(doubleValue[i])),
943 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
944
945 assertEquals("Result of operation",
946 doubleType ? Math.floor(doubleValue[i]) : ((float) Math.floor(doubleValue[i])),
947 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
948 }
949
950 left = findAndExecuteConstructor(vectorClass,
951 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
952 mathMethod = ClassUtil.resolveMethod(vectorClass, "rint", new Class[] {});
953 mathMethod.setAccessible(true);
954 result = mathMethod.invoke(left);
955 for (int i = 0; i < doubleValue.length; i++)
956 {
957 assertEquals("Result of operation",
958 doubleType ? Math.rint(doubleValue[i]) : ((float) Math.rint(doubleValue[i])),
959 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
960
961 assertEquals("Result of operation",
962 doubleType ? Math.rint(doubleValue[i]) : ((float) Math.rint(doubleValue[i])),
963 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
964 }
965
966 left = findAndExecuteConstructor(vectorClass,
967 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
968 mathMethod = ClassUtil.resolveMethod(vectorClass, "round", new Class[] {});
969 mathMethod.setAccessible(true);
970 result = mathMethod.invoke(left);
971 for (int i = 0; i < doubleValue.length; i++)
972 {
973 assertEquals("Result of operation",
974 doubleType ? Math.round(doubleValue[i]) : ((float) Math.round(doubleValue[i])),
975 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
976
977 assertEquals("Result of operation",
978 doubleType ? Math.round(doubleValue[i]) : ((float) Math.round(doubleValue[i])),
979 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
980 }
981
982 if (!abs)
983 {
984 left = findAndExecuteConstructor(vectorClass,
985 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
986 mathMethod = ClassUtil.resolveMethod(vectorClass, "abs", new Class[] {});
987 mathMethod.setAccessible(true);
988 result = mathMethod.invoke(left);
989 for (int i = 0; i < doubleValue.length; i++)
990 {
991 assertEquals("Result of operation",
992 doubleType ? Math.abs(doubleValue[i]) : ((float) Math.abs(doubleValue[i])),
993 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
994
995 assertEquals("Result of operation",
996 doubleType ? Math.abs(doubleValue[i]) : ((float) Math.abs(doubleValue[i])),
997 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
998 }
999 }
1000
1001 if (vectorClass.getName().contains("Dimensionless"))
1002 {
1003 left = findAndExecuteConstructor(vectorClass,
1004 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1005 mathMethod = ClassUtil.resolveMethod(vectorClass, "acos", new Class[] {});
1006 mathMethod.setAccessible(true);
1007 result = mathMethod.invoke(left);
1008 for (int i = 0; i < doubleValue.length; i++)
1009 {
1010 assertEquals("Result of operation",
1011 doubleType ? Math.acos(doubleValue[i]) : ((float) Math.acos(doubleValue[i])),
1012 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1013
1014 assertEquals("Result of operation",
1015 doubleType ? Math.acos(doubleValue[i]) : ((float) Math.acos(doubleValue[i])),
1016 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1017 }
1018
1019 left = findAndExecuteConstructor(vectorClass,
1020 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1021 mathMethod = ClassUtil.resolveMethod(vectorClass, "asin", new Class[] {});
1022 mathMethod.setAccessible(true);
1023 result = mathMethod.invoke(left);
1024 for (int i = 0; i < doubleValue.length; i++)
1025 {
1026 assertEquals("Result of operation",
1027 doubleType ? Math.asin(doubleValue[i]) : ((float) Math.asin(doubleValue[i])),
1028 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1029
1030 assertEquals("Result of operation",
1031 doubleType ? Math.asin(doubleValue[i]) : ((float) Math.asin(doubleValue[i])),
1032 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1033 }
1034
1035 left = findAndExecuteConstructor(vectorClass,
1036 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1037 mathMethod = ClassUtil.resolveMethod(vectorClass, "atan", new Class[] {});
1038 mathMethod.setAccessible(true);
1039 result = mathMethod.invoke(left);
1040 for (int i = 0; i < doubleValue.length; i++)
1041 {
1042 assertEquals("Result of operation",
1043 doubleType ? Math.atan(doubleValue[i]) : ((float) Math.atan(doubleValue[i])),
1044 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1045
1046 assertEquals("Result of operation",
1047 doubleType ? Math.atan(doubleValue[i]) : ((float) Math.atan(doubleValue[i])),
1048 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1049 }
1050
1051 left = findAndExecuteConstructor(vectorClass,
1052 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1053 mathMethod = ClassUtil.resolveMethod(vectorClass, "cbrt", new Class[] {});
1054 mathMethod.setAccessible(true);
1055 result = mathMethod.invoke(left);
1056 for (int i = 0; i < doubleValue.length; i++)
1057 {
1058 assertEquals("Result of operation",
1059 doubleType ? Math.cbrt(doubleValue[i]) : ((float) Math.cbrt(doubleValue[i])),
1060 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1061
1062 assertEquals("Result of operation",
1063 doubleType ? Math.cbrt(doubleValue[i]) : ((float) Math.cbrt(doubleValue[i])),
1064 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1065 }
1066
1067 left = findAndExecuteConstructor(vectorClass,
1068 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1069 mathMethod = ClassUtil.resolveMethod(vectorClass, "cos", new Class[] {});
1070 mathMethod.setAccessible(true);
1071 result = mathMethod.invoke(left);
1072 for (int i = 0; i < doubleValue.length; i++)
1073 {
1074 assertEquals("Result of operation",
1075 doubleType ? Math.cos(doubleValue[i]) : ((float) Math.cos(doubleValue[i])),
1076 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1077
1078 assertEquals("Result of operation",
1079 doubleType ? Math.cos(doubleValue[i]) : ((float) Math.cos(doubleValue[i])),
1080 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1081 }
1082
1083 left = findAndExecuteConstructor(vectorClass,
1084 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1085 mathMethod = ClassUtil.resolveMethod(vectorClass, "cosh", new Class[] {});
1086 mathMethod.setAccessible(true);
1087 result = mathMethod.invoke(left);
1088 for (int i = 0; i < doubleValue.length; i++)
1089 {
1090 assertEquals("Result of operation",
1091 doubleType ? Math.cosh(doubleValue[i]) : ((float) Math.cosh(doubleValue[i])),
1092 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1093
1094 assertEquals("Result of operation",
1095 doubleType ? Math.cosh(doubleValue[i]) : ((float) Math.cosh(doubleValue[i])),
1096 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1097 }
1098
1099 left = findAndExecuteConstructor(vectorClass,
1100 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1101 mathMethod = ClassUtil.resolveMethod(vectorClass, "exp", new Class[] {});
1102 mathMethod.setAccessible(true);
1103 result = mathMethod.invoke(left);
1104 for (int i = 0; i < doubleValue.length; i++)
1105 {
1106 assertEquals("Result of operation",
1107 doubleType ? Math.exp(doubleValue[i]) : ((float) Math.exp(doubleValue[i])),
1108 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1109
1110 assertEquals("Result of operation",
1111 doubleType ? Math.exp(doubleValue[i]) : ((float) Math.exp(doubleValue[i])),
1112 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1113 }
1114
1115 left = findAndExecuteConstructor(vectorClass,
1116 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1117 mathMethod = ClassUtil.resolveMethod(vectorClass, "expm1", new Class[] {});
1118 mathMethod.setAccessible(true);
1119 result = mathMethod.invoke(left);
1120 for (int i = 0; i < doubleValue.length; i++)
1121 {
1122 assertEquals("Result of operation",
1123 doubleType ? Math.expm1(doubleValue[i]) : ((float) Math.expm1(doubleValue[i])),
1124 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1125
1126 assertEquals("Result of operation",
1127 doubleType ? Math.expm1(doubleValue[i]) : ((float) Math.expm1(doubleValue[i])),
1128 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1129 }
1130
1131 left = findAndExecuteConstructor(vectorClass,
1132 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1133 mathMethod = ClassUtil.resolveMethod(vectorClass, "log", new Class[] {});
1134 mathMethod.setAccessible(true);
1135 result = mathMethod.invoke(left);
1136 for (int i = 0; i < doubleValue.length; i++)
1137 {
1138 assertEquals("Result of operation",
1139 doubleType ? Math.log(doubleValue[i]) : ((float) Math.log(doubleValue[i])),
1140 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1141
1142 assertEquals("Result of operation",
1143 doubleType ? Math.log(doubleValue[i]) : ((float) Math.log(doubleValue[i])),
1144 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1145 }
1146
1147 left = findAndExecuteConstructor(vectorClass,
1148 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1149 mathMethod = ClassUtil.resolveMethod(vectorClass, "log10", new Class[] {});
1150 mathMethod.setAccessible(true);
1151 result = mathMethod.invoke(left);
1152 for (int i = 0; i < doubleValue.length; i++)
1153 {
1154 assertEquals("Result of operation",
1155 doubleType ? Math.log10(doubleValue[i]) : ((float) Math.log10(doubleValue[i])),
1156 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1157
1158 assertEquals("Result of operation",
1159 doubleType ? Math.log10(doubleValue[i]) : ((float) Math.log10(doubleValue[i])),
1160 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1161 }
1162
1163 left = findAndExecuteConstructor(vectorClass,
1164 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1165 mathMethod = ClassUtil.resolveMethod(vectorClass, "log1p", new Class[] {});
1166 mathMethod.setAccessible(true);
1167 result = mathMethod.invoke(left);
1168 for (int i = 0; i < doubleValue.length; i++)
1169 {
1170 assertEquals("Result of operation",
1171 doubleType ? Math.log1p(doubleValue[i]) : ((float) Math.log1p(doubleValue[i])),
1172 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1173
1174 assertEquals("Result of operation",
1175 doubleType ? Math.log1p(doubleValue[i]) : ((float) Math.log1p(doubleValue[i])),
1176 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1177 }
1178
1179 left = findAndExecuteConstructor(vectorClass,
1180 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1181 mathMethod = ClassUtil.resolveMethod(vectorClass, "signum", new Class[] {});
1182 mathMethod.setAccessible(true);
1183 result = mathMethod.invoke(left);
1184 for (int i = 0; i < doubleValue.length; i++)
1185 {
1186 assertEquals("Result of operation",
1187 doubleType ? Math.signum(doubleValue[i]) : ((float) Math.signum(doubleValue[i])),
1188 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1189
1190 assertEquals("Result of operation",
1191 doubleType ? Math.signum(doubleValue[i]) : ((float) Math.signum(doubleValue[i])),
1192 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1193 }
1194
1195 left = findAndExecuteConstructor(vectorClass,
1196 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1197 mathMethod = ClassUtil.resolveMethod(vectorClass, "sin", new Class[] {});
1198 mathMethod.setAccessible(true);
1199 result = mathMethod.invoke(left);
1200 for (int i = 0; i < doubleValue.length; i++)
1201 {
1202 assertEquals("Result of operation",
1203 doubleType ? Math.sin(doubleValue[i]) : ((float) Math.sin(doubleValue[i])),
1204 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1205
1206 assertEquals("Result of operation",
1207 doubleType ? Math.sin(doubleValue[i]) : ((float) Math.sin(doubleValue[i])),
1208 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1209 }
1210
1211 left = findAndExecuteConstructor(vectorClass,
1212 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1213 mathMethod = ClassUtil.resolveMethod(vectorClass, "sinh", new Class[] {});
1214 mathMethod.setAccessible(true);
1215 result = mathMethod.invoke(left);
1216 for (int i = 0; i < doubleValue.length; i++)
1217 {
1218 assertEquals("Result of operation",
1219 doubleType ? Math.sinh(doubleValue[i]) : ((float) Math.sinh(doubleValue[i])),
1220 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1221
1222 assertEquals("Result of operation",
1223 doubleType ? Math.sinh(doubleValue[i]) : ((float) Math.sinh(doubleValue[i])),
1224 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1225 }
1226
1227 left = findAndExecuteConstructor(vectorClass,
1228 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1229 mathMethod = ClassUtil.resolveMethod(vectorClass, "sqrt", new Class[] {});
1230 mathMethod.setAccessible(true);
1231 result = mathMethod.invoke(left);
1232 for (int i = 0; i < doubleValue.length; i++)
1233 {
1234 assertEquals("Result of operation",
1235 doubleType ? Math.sqrt(doubleValue[i]) : ((float) Math.sqrt(doubleValue[i])),
1236 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1237
1238 assertEquals("Result of operation",
1239 doubleType ? Math.sqrt(doubleValue[i]) : ((float) Math.sqrt(doubleValue[i])),
1240 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1241 }
1242
1243 left = findAndExecuteConstructor(vectorClass,
1244 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1245 mathMethod = ClassUtil.resolveMethod(vectorClass, "tan", new Class[] {});
1246 mathMethod.setAccessible(true);
1247 result = mathMethod.invoke(left);
1248 for (int i = 0; i < doubleValue.length; i++)
1249 {
1250 assertEquals("Result of operation",
1251 doubleType ? Math.tan(doubleValue[i]) : ((float) Math.tan(doubleValue[i])),
1252 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1253
1254 assertEquals("Result of operation",
1255 doubleType ? Math.tan(doubleValue[i]) : ((float) Math.tan(doubleValue[i])),
1256 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1257 }
1258
1259 left = findAndExecuteConstructor(vectorClass,
1260 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1261 mathMethod = ClassUtil.resolveMethod(vectorClass, "tanh", new Class[] {});
1262 mathMethod.setAccessible(true);
1263 result = mathMethod.invoke(left);
1264 for (int i = 0; i < doubleValue.length; i++)
1265 {
1266 assertEquals("Result of operation",
1267 doubleType ? Math.tanh(doubleValue[i]) : ((float) Math.tanh(doubleValue[i])),
1268 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1269
1270 assertEquals("Result of operation",
1271 doubleType ? Math.tanh(doubleValue[i]) : ((float) Math.tanh(doubleValue[i])),
1272 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1273 }
1274
1275 left = findAndExecuteConstructor(vectorClass,
1276 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1277 mathMethod = ClassUtil.resolveMethod(vectorClass, "inv", new Class[] {});
1278 mathMethod.setAccessible(true);
1279 result = mathMethod.invoke(left);
1280 for (int i = 0; i < doubleValue.length; i++)
1281 {
1282 assertEquals("Result of operation", doubleType ? (1.0 / doubleValue[i]) : ((float) (1.0 / doubleValue[i])),
1283 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1284
1285 assertEquals("Result of operation", doubleType ? (1.0 / doubleValue[i]) : ((float) (1.0 / doubleValue[i])),
1286 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1287 }
1288
1289 for (double power : new double[] { -3, -Math.PI, -1, -0.5, 0, 0.5, 1, Math.PI, 3 })
1290 {
1291 left = findAndExecuteConstructor(vectorClass,
1292 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1293 mathMethod = ClassUtil.resolveMethod(vectorClass, "pow", new Class[] { double.class });
1294 mathMethod.setAccessible(true);
1295 result = mathMethod.invoke(left, power);
1296 for (int i = 0; i < doubleValue.length; i++)
1297 {
1298 assertEquals("Result of operation",
1299 doubleType ? Math.pow(doubleValue[i], power) : ((float) Math.pow(doubleValue[i], power)),
1300 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1301
1302 assertEquals("Result of operation",
1303 doubleType ? Math.pow(doubleValue[i], power) : ((float) Math.pow(doubleValue[i], power)),
1304 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1305 }
1306 }
1307
1308 left = findAndExecuteConstructor(vectorClass,
1309 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1310 mathMethod = ClassUtil.resolveMethod(vectorClass, "normalize", new Class[] {});
1311 mathMethod.setAccessible(true);
1312 mathMethod.invoke(left);
1313 double sum = 0;
1314 for (double v : doubleValue)
1315 {
1316 sum += v;
1317 }
1318 for (int i = 0; i < doubleValue.length; i++)
1319 {
1320 assertEquals("Result of operation", doubleType ? (doubleValue[i] / sum) : ((float) (doubleValue[i] / sum)),
1321 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1322 }
1323
1324 double[] doubleZeroZSum = { -4, 4, -1, 1, 0 };
1325 float[] floatZeroZSum = { -4, 4, -1, 1, 0 };
1326 Object zeroZSumValue = doubleType ? doubleZeroZSum : floatZeroZSum;
1327 left = findAndExecuteConstructor(vectorClass,
1328 new Object[] { zeroZSumValue, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1329 try
1330 {
1331 mathMethod.invoke(left);
1332 fail("normalize should have thrown a ValueException because zSum is 0");
1333 }
1334 catch (Exception ve)
1335 {
1336 if (!(ve.getCause() instanceof ValueException))
1337 {
1338 fail("Thrown exception should have been a ValueException");
1339 }
1340
1341 }
1342
1343 }
1344 }
1345
1346 left = findAndExecuteConstructor(vectorClass,
1347 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1348 if (mutable)
1349 {
1350 Method multiplyBy =
1351 ClassUtil.resolveMethod(vectorClass, "multiplyBy", new Class[] { doubleType ? double.class : float.class });
1352 multiplyBy.setAccessible(true);
1353 if (doubleType)
1354 {
1355 result = multiplyBy.invoke(left, Math.PI);
1356 }
1357 else
1358 {
1359 result = multiplyBy.invoke(left, (float) Math.PI);
1360 }
1361 for (int i = 0; i < doubleValue.length; i++)
1362 {
1363 assertEquals("Result of operation", doubleValue[i] * Math.PI,
1364 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1365
1366 assertEquals("Result of operation", doubleValue[i] * Math.PI,
1367 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1368 }
1369 left = findAndExecuteConstructor(vectorClass,
1370 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1371 Method divideBy =
1372 ClassUtil.resolveMethod(vectorClass, "divideBy", new Class[] { doubleType ? double.class : float.class });
1373 divideBy.setAccessible(true);
1374 if (doubleType)
1375 {
1376 result = divideBy.invoke(left, Math.PI);
1377 }
1378 else
1379 {
1380 result = divideBy.invoke(left, (float) Math.PI);
1381 }
1382 for (int i = 0; i < doubleValue.length; i++)
1383 {
1384 assertEquals("Result of operation", doubleValue[i] / Math.PI,
1385 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1386
1387 assertEquals("Result of operation", doubleValue[i] / Math.PI,
1388 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1389 }
1390 double[] zDoubleValues = { 0, 0, 0, 0, 0, 0, 0 };
1391 float[] zFloatValues = { 0, 0, 0, 0, 0, 0, 0 };
1392 Object zValues = doubleType ? zDoubleValues : zFloatValues;
1393 Method set = ClassUtil.resolveMethod(vectorClass, "setSI",
1394 new Class[] { int.class, doubleType ? double.class : float.class });
1395 set.setAccessible(true);
1396 for (int pivot2 = 0; pivot2 < zDoubleValues.length; pivot2++)
1397 {
1398 for (int pivot = 0; pivot < zDoubleValues.length; pivot++)
1399 {
1400 if (pivot == pivot2)
1401 {
1402 continue;
1403 }
1404 left = findAndExecuteConstructor(vectorClass,
1405 new Object[] { zValues, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1406
1407 if (doubleType)
1408 {
1409 set.invoke(left, new Object[] { pivot, Math.PI * (pivot + 1) });
1410 }
1411 else
1412 {
1413 set.invoke(left, new Object[] { pivot, (float) (Math.PI * (pivot + 1)) });
1414 }
1415
1416 for (int i = 0; i < zDoubleValues.length; i++)
1417 {
1418 assertEquals("after one set, i=" + i, i == pivot ? Math.PI * (pivot + 1) : 0,
1419 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1420 }
1421 if (doubleType)
1422 {
1423 set.invoke(left, new Object[] { pivot2, Math.PI * (pivot2 + 20) });
1424 }
1425 else
1426 {
1427 set.invoke(left, new Object[] { pivot2, (float) (Math.PI * (pivot2 + 20)) });
1428 }
1429
1430 for (int i = 0; i < zDoubleValues.length; i++)
1431 {
1432 assertEquals("after second set, i=" + i,
1433 i == pivot ? Math.PI * (pivot + 1) : i == pivot2 ? Math.PI * (pivot2 + 20) : 0,
1434 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1435 }
1436 for (int i = 0; i < zDoubleValues.length; i++)
1437 {
1438 if (i == pivot || i == pivot2)
1439 {
1440 continue;
1441 }
1442 if (doubleType)
1443 {
1444 set.invoke(left, new Object[] { i, (double) (i + 1) });
1445 }
1446 else
1447 {
1448 set.invoke(left, new Object[] { i, (float) (i + 1) });
1449 }
1450 }
1451
1452 for (int i = 0; i < zDoubleValues.length; i++)
1453 {
1454 assertEquals("after all set i=" + i + " pivot=" + pivot + ", pivot2=" + pivot2,
1455 i == pivot ? Math.PI * (pivot + 1) : i == pivot2 ? Math.PI * (pivot2 + 20) : i + 1,
1456 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, left, i), 0.01);
1457 }
1458 }
1459 }
1460 }
1461 Object compatibleRight = null;
1462 Object compatibleRel = null;
1463
1464 if (!vectorClass.getName().contains("Money") && !vectorClass.getName().contains("Dimensionless")
1465 && !vectorClass.getName().contains("Temperature") && !vectorClass.getName().contains("Position")
1466 && !vectorClass.getName().contains("Time") && !vectorClass.getName().contains("Direction"))
1467 {
1468
1469 Class<?> unitClass = getUnitClass(vectorClass);
1470 UnitSystem unitSystem = UnitSystem.SI_DERIVED;
1471 Unit<?> referenceUnit;
1472
1473 Method getUnitMethod = ClassUtil.resolveMethod(vectorClass, "getUnit");
1474 referenceUnit = (Unit<?>) getUnitMethod.invoke(left);
1475 Constructor<?> unitConstructor =
1476 unitClass.getConstructor(String.class, String.class, UnitSystem.class, unitClass, double.class);
1477 Object newUnit = unitConstructor.newInstance("7fullName", "7abbr", unitSystem, referenceUnit, 7d);
1478
1479 compatibleRight = findAndExecuteConstructor(vectorClass, new Object[] { value, newUnit, storageType }, doubleType);
1480
1481 if (abs)
1482 {
1483 String className = vectorClass.getName();
1484 for (int i = 0; i < CLASSNAMES_ABS.length; i++)
1485 {
1486 className = className.replaceAll(CLASSNAMES_ABS[i], CLASSNAMES_ABS_REL[i]);
1487 }
1488 Class<?> relClass = Class.forName(className);
1489 compatibleRel = findAndExecuteConstructor(relClass, new Object[] { value, newUnit, storageType }, doubleType);
1490
1491 }
1492 }
1493 if (null != compatibleRight)
1494 {
1495 left = findAndExecuteConstructor(vectorClass,
1496 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1497
1498
1499 if (!mutable)
1500 {
1501
1502 if (!abs)
1503 {
1504 Method plus = ClassUtil.resolveMethod(vectorClass, "plus",
1505 new Class<?>[] { compatibleRight.getClass().getSuperclass() });
1506 plus.setAccessible(true);
1507 result = plus.invoke(left, compatibleRight);
1508 for (int i = 0; i < doubleValue.length; i++)
1509 {
1510 assertEquals("Result of mixed operation", 8 * doubleValue[i],
1511 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1512 }
1513 }
1514 if (null != compatibleRel)
1515 {
1516
1517
1518 Method plus = ClassUtil.resolveMethod(vectorClass, "plus",
1519 new Class<?>[] { compatibleRel.getClass().getSuperclass() });
1520 plus.setAccessible(true);
1521 result = plus.invoke(left, compatibleRel);
1522 for (int i = 0; i < doubleValue.length; i++)
1523 {
1524 assertEquals("Result of mixed operation", 8 * doubleValue[i],
1525 verifyAbsRelPrecisionAndExtractSI(abs, doubleType, storageType, result, i), 0.01);
1526 }
1527 }
1528 }
1529 }
1530 left = findAndExecuteConstructor(vectorClass,
1531 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1532 if (!mutable)
1533 {
1534
1535 Method minus = ClassUtil.resolveMethod(vectorClass, "minus", new Class[] { vectorClass.getSuperclass() });
1536 minus.setAccessible(true);
1537 result = minus.invoke(left, left);
1538 for (int i = 0; i < doubleValue.length; i++)
1539 {
1540 assertEquals("Result of minus", 0, verifyAbsRelPrecisionAndExtractSI(false, doubleType, storageType, result, i),
1541 0.01);
1542 }
1543 if (null != compatibleRight)
1544 {
1545 left = findAndExecuteConstructor(vectorClass,
1546 new Object[] { value, getSIUnitInstance(getUnitClass(vectorClass)), storageType }, doubleType);
1547 result = minus.invoke(left, compatibleRight);
1548 for (int i = 0; i < doubleValue.length; i++)
1549 {
1550 assertEquals("Result of minus with compatible arg", -6 * doubleValue[i],
1551 verifyAbsRelPrecisionAndExtractSI(false, doubleType, storageType, result, i), 0.01);
1552 }
1553 }
1554 }
1555 }
1556
1557
1558
1559
1560
1561
1562
1563
1564 public final String listMethods(final Class<?> theClass, final String name, final String prefix)
1565 {
1566 StringBuilder result = new StringBuilder();
1567 for (Method m : theClass.getMethods())
1568 {
1569 if (null == name || name.equals(m.getName()))
1570 {
1571 result.append(
1572 prefix + m.getName() + paramsToString(m.getParameterTypes()) + " -> " + m.getReturnType() + "\r\n");
1573 }
1574 }
1575 return result.toString();
1576 }
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591 private void testInterpolateMethod(final Class<?> vectorClass, final boolean abs, final boolean doubleType,
1592 final StorageType storageType) throws NoSuchMethodException, InstantiationException, IllegalAccessException,
1593 InvocationTargetException, NoSuchFieldException, ValueException
1594 {
1595
1596 Constructor<?> constructor = vectorClass.getConstructor(doubleType ? double[].class : float[].class,
1597 getUnitClass(vectorClass), StorageType.class);
1598 if (doubleType)
1599 {
1600 double[] zeroValue = { 1.23456, 2.45678 };
1601
1602
1603
1604
1605 AbstractDoubleVector<?, ?> zero = (AbstractDoubleVector<?, ?>) constructor.newInstance(zeroValue,
1606 getSIUnitInstance(getUnitClass(vectorClass)), storageType);
1607 double[] oneValue = { 3.45678, 4.678901 };
1608 AbstractDoubleVector<?, ?> one = (AbstractDoubleVector<?, ?>) constructor.newInstance(oneValue,
1609 getSIUnitInstance(getUnitClass(vectorClass)), storageType);
1610 for (double ratio : new double[] { -5, -1, 0, 0.3, 1, 2, 10 })
1611 {
1612 double[] expectedResult = new double[zeroValue.length];
1613 for (int i = 0; i < expectedResult.length; i++)
1614 {
1615 expectedResult[i] = (1.0 - ratio) * zeroValue[i] + ratio * oneValue[i];
1616 }
1617
1618
1619
1620
1621
1622
1623 }
1624 }
1625 else
1626 {
1627 float[] zeroValue = { 1.23456f, 2.45678f };
1628 AbstractFloatVector<?, ?> zero = (AbstractFloatVector<?, ?>) constructor.newInstance(zeroValue,
1629 getSIUnitInstance(getUnitClass(vectorClass)), storageType);
1630 float[] oneValue = { 3.45678f, 4.678901f };
1631 AbstractFloatVector<?, ?> one = (AbstractFloatVector<?, ?>) constructor.newInstance(oneValue,
1632 getSIUnitInstance(getUnitClass(vectorClass)), storageType);
1633 for (float ratio : new float[] { -5, -1, 0, 0.3f, 1, 2, 10 })
1634 {
1635 float[] expectedResult = new float[zeroValue.length];
1636 for (int i = 0; i < expectedResult.length; i++)
1637 {
1638 expectedResult[i] = (float) ((1.0 - ratio) * zeroValue[i] + ratio * oneValue[i]);
1639 }
1640
1641
1642
1643
1644
1645 }
1646 }
1647 }
1648
1649
1650
1651
1652
1653
1654
1655 public static void main(final String[] args) throws ValueException
1656 {
1657 Length l = new Length(3, METER);
1658 Length w = new Length(2, METER);
1659 Area area = l.multiplyBy(w);
1660 System.out.println("Area is " + area);
1661
1662
1663
1664
1665
1666
1667
1668
1669 int size = 100000000;
1670 int[] a = new int[size];
1671 for (int i = 0; i < size; i++)
1672 {
1673 a[i] = i;
1674 }
1675
1676 int[] b = Arrays.stream(a).parallel().toArray();
1677 for (int i = 0; i < size; i++)
1678 {
1679 if (b[i] != i)
1680 {
1681 System.out.println("Oops b[" + i + "] is " + b[i]);
1682 }
1683 }
1684 System.out.println("finished");
1685 }
1686 }