1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.analysis.differentiation;
18
19 import java.util.Arrays;
20
21 import org.apache.commons.numbers.core.Sum;
22 import org.apache.commons.math4.legacy.core.Field;
23 import org.apache.commons.math4.legacy.core.FieldElement;
24 import org.apache.commons.math4.legacy.core.RealFieldElement;
25 import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
26 import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException;
27 import org.apache.commons.math4.core.jdkmath.JdkMath;
28 import org.apache.commons.math4.legacy.core.MathArrays;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class DerivativeStructure implements RealFieldElement<DerivativeStructure> {
61
62 private DSCompiler compiler;
63
64
65 private final double[] data;
66
67
68
69
70 private DerivativeStructure(final DSCompiler compiler) {
71 this.compiler = compiler;
72 this.data = new double[compiler.getSize()];
73 }
74
75
76
77
78
79
80 public DerivativeStructure(final int parameters, final int order) {
81 this(DSCompiler.getCompiler(parameters, order));
82 }
83
84
85
86
87
88
89
90
91 public DerivativeStructure(final int parameters, final int order, final double value) {
92 this(parameters, order);
93 this.data[0] = value;
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107
108 public DerivativeStructure(final int parameters, final int order,
109 final int index, final double value) {
110 this(parameters, order, value);
111
112 if (index >= parameters) {
113 throw new NumberIsTooLargeException(index, parameters, false);
114 }
115
116 if (order > 0) {
117
118 data[DSCompiler.getCompiler(index, order).getSize()] = 1.0;
119 }
120 }
121
122
123
124
125
126
127
128
129
130
131 public DerivativeStructure(final double a1, final DerivativeStructure ds1,
132 final double a2, final DerivativeStructure ds2) {
133 this(ds1.compiler);
134 compiler.checkCompatibility(ds2.compiler);
135 compiler.linearCombination(a1, ds1.data, 0, a2, ds2.data, 0, data, 0);
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149 public DerivativeStructure(final double a1, final DerivativeStructure ds1,
150 final double a2, final DerivativeStructure ds2,
151 final double a3, final DerivativeStructure ds3) {
152 this(ds1.compiler);
153 compiler.checkCompatibility(ds2.compiler);
154 compiler.checkCompatibility(ds3.compiler);
155 compiler.linearCombination(a1, ds1.data, 0, a2, ds2.data, 0, a3, ds3.data, 0, data, 0);
156 }
157
158
159
160
161
162
163
164
165
166
167
168
169
170 public DerivativeStructure(final double a1, final DerivativeStructure ds1,
171 final double a2, final DerivativeStructure ds2,
172 final double a3, final DerivativeStructure ds3,
173 final double a4, final DerivativeStructure ds4) {
174 this(ds1.compiler);
175 compiler.checkCompatibility(ds2.compiler);
176 compiler.checkCompatibility(ds3.compiler);
177 compiler.checkCompatibility(ds4.compiler);
178 compiler.linearCombination(a1, ds1.data, 0, a2, ds2.data, 0,
179 a3, ds3.data, 0, a4, ds4.data, 0,
180 data, 0);
181 }
182
183
184
185
186
187
188
189
190
191
192
193 public DerivativeStructure(final int parameters, final int order, final double ... derivatives) {
194 this(parameters, order);
195 if (derivatives.length != data.length) {
196 throw new DimensionMismatchException(derivatives.length, data.length);
197 }
198 System.arraycopy(derivatives, 0, data, 0, data.length);
199 }
200
201
202
203
204 private DerivativeStructure(final DerivativeStructure ds) {
205 this.compiler = ds.compiler;
206 this.data = ds.data.clone();
207 }
208
209
210
211
212 public int getFreeParameters() {
213 return compiler.getFreeParameters();
214 }
215
216
217
218
219 public int getOrder() {
220 return compiler.getOrder();
221 }
222
223
224
225
226
227
228
229
230
231
232
233 public DerivativeStructure createConstant(final double c) {
234 return new DerivativeStructure(getFreeParameters(), getOrder(), c);
235 }
236
237
238
239
240 @Override
241 public double getReal() {
242 return data[0];
243 }
244
245
246
247
248
249 public double getValue() {
250 return data[0];
251 }
252
253
254
255
256
257
258
259
260
261
262
263 public double getPartialDerivative(final int ... orders) {
264 return data[compiler.getPartialDerivativeIndex(orders)];
265 }
266
267
268
269
270
271 public double[] getAllDerivatives() {
272 return data.clone();
273 }
274
275
276
277
278 @Override
279 public DerivativeStructure add(final double a) {
280 final DerivativeStructure ds = new DerivativeStructure(this);
281 ds.data[0] += a;
282 return ds;
283 }
284
285
286
287
288
289 @Override
290 public DerivativeStructure add(final DerivativeStructure a) {
291 compiler.checkCompatibility(a.compiler);
292 final DerivativeStructure ds = new DerivativeStructure(this);
293 compiler.add(data, 0, a.data, 0, ds.data, 0);
294 return ds;
295 }
296
297
298
299
300 @Override
301 public DerivativeStructure subtract(final double a) {
302 return add(-a);
303 }
304
305
306
307
308
309 @Override
310 public DerivativeStructure subtract(final DerivativeStructure a) {
311 compiler.checkCompatibility(a.compiler);
312 final DerivativeStructure ds = new DerivativeStructure(this);
313 compiler.subtract(data, 0, a.data, 0, ds.data, 0);
314 return ds;
315 }
316
317
318 @Override
319 public DerivativeStructure multiply(final int n) {
320 return multiply((double) n);
321 }
322
323
324
325
326 @Override
327 public DerivativeStructure multiply(final double a) {
328 final DerivativeStructure ds = new DerivativeStructure(this);
329 for (int i = 0; i < ds.data.length; ++i) {
330 ds.data[i] *= a;
331 }
332 return ds;
333 }
334
335
336
337
338
339 @Override
340 public DerivativeStructure multiply(final DerivativeStructure a) {
341 compiler.checkCompatibility(a.compiler);
342 final DerivativeStructure result = new DerivativeStructure(compiler);
343 compiler.multiply(data, 0, a.data, 0, result.data, 0);
344 return result;
345 }
346
347
348
349
350 @Override
351 public DerivativeStructure divide(final double a) {
352 final DerivativeStructure ds = new DerivativeStructure(this);
353 for (int i = 0; i < ds.data.length; ++i) {
354 ds.data[i] /= a;
355 }
356 return ds;
357 }
358
359
360
361
362
363 @Override
364 public DerivativeStructure divide(final DerivativeStructure a) {
365 compiler.checkCompatibility(a.compiler);
366 final DerivativeStructure result = new DerivativeStructure(compiler);
367 compiler.divide(data, 0, a.data, 0, result.data, 0);
368 return result;
369 }
370
371
372 @Override
373 public DerivativeStructure remainder(final double a) {
374 final DerivativeStructure ds = new DerivativeStructure(this);
375 ds.data[0] = JdkMath.IEEEremainder(ds.data[0], a);
376 return ds;
377 }
378
379
380
381
382
383
384 @Override
385 public DerivativeStructure remainder(final DerivativeStructure a) {
386 compiler.checkCompatibility(a.compiler);
387 final DerivativeStructure result = new DerivativeStructure(compiler);
388 compiler.remainder(data, 0, a.data, 0, result.data, 0);
389 return result;
390 }
391
392
393 @Override
394 public DerivativeStructure negate() {
395 final DerivativeStructure ds = new DerivativeStructure(compiler);
396 for (int i = 0; i < ds.data.length; ++i) {
397 ds.data[i] = -data[i];
398 }
399 return ds;
400 }
401
402
403
404
405 @Override
406 public DerivativeStructure abs() {
407 if (Double.doubleToLongBits(data[0]) < 0) {
408
409 return negate();
410 } else {
411 return this;
412 }
413 }
414
415
416
417
418 @Override
419 public DerivativeStructure ceil() {
420 return new DerivativeStructure(compiler.getFreeParameters(),
421 compiler.getOrder(),
422 JdkMath.ceil(data[0]));
423 }
424
425
426
427
428 @Override
429 public DerivativeStructure floor() {
430 return new DerivativeStructure(compiler.getFreeParameters(),
431 compiler.getOrder(),
432 JdkMath.floor(data[0]));
433 }
434
435
436
437
438 @Override
439 public DerivativeStructure rint() {
440 return new DerivativeStructure(compiler.getFreeParameters(),
441 compiler.getOrder(),
442 JdkMath.rint(data[0]));
443 }
444
445
446 @Override
447 public long round() {
448 return JdkMath.round(data[0]);
449 }
450
451
452
453
454 @Override
455 public DerivativeStructure signum() {
456 return new DerivativeStructure(compiler.getFreeParameters(),
457 compiler.getOrder(),
458 JdkMath.signum(data[0]));
459 }
460
461
462
463
464 @Override
465 public DerivativeStructure copySign(final DerivativeStructure sign){
466 long m = Double.doubleToLongBits(data[0]);
467 long s = Double.doubleToLongBits(sign.data[0]);
468 if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) {
469 return this;
470 }
471 return negate();
472 }
473
474
475
476
477 @Override
478 public DerivativeStructure copySign(final double sign) {
479 long m = Double.doubleToLongBits(data[0]);
480 long s = Double.doubleToLongBits(sign);
481 if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) {
482 return this;
483 }
484 return negate();
485 }
486
487
488
489
490
491
492
493
494
495 public int getExponent() {
496 return JdkMath.getExponent(data[0]);
497 }
498
499
500
501
502 @Override
503 public DerivativeStructure scalb(final int n) {
504 final DerivativeStructure ds = new DerivativeStructure(compiler);
505 for (int i = 0; i < ds.data.length; ++i) {
506 ds.data[i] = JdkMath.scalb(data[i], n);
507 }
508 return ds;
509 }
510
511
512
513
514
515
516 @Override
517 public DerivativeStructure hypot(final DerivativeStructure y) {
518 compiler.checkCompatibility(y.compiler);
519
520 if (Double.isInfinite(data[0]) || Double.isInfinite(y.data[0])) {
521 return new DerivativeStructure(compiler.getFreeParameters(),
522 compiler.getFreeParameters(),
523 Double.POSITIVE_INFINITY);
524 } else if (Double.isNaN(data[0]) || Double.isNaN(y.data[0])) {
525 return new DerivativeStructure(compiler.getFreeParameters(),
526 compiler.getFreeParameters(),
527 Double.NaN);
528 } else {
529
530 final int expX = getExponent();
531 final int expY = y.getExponent();
532 if (expX > expY + 27) {
533
534 return abs();
535 } else if (expY > expX + 27) {
536
537 return y.abs();
538 } else {
539
540
541 final int middleExp = (expX + expY) / 2;
542
543
544 final DerivativeStructure scaledX = scalb(-middleExp);
545 final DerivativeStructure scaledY = y.scalb(-middleExp);
546
547
548 final DerivativeStructure scaledH =
549 scaledX.multiply(scaledX).add(scaledY.multiply(scaledY)).sqrt();
550
551
552 return scaledH.scalb(middleExp);
553 }
554 }
555 }
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574 public static DerivativeStructure hypot(final DerivativeStructure x, final DerivativeStructure y) {
575 return x.hypot(y);
576 }
577
578
579
580
581
582
583
584
585
586 public DerivativeStructure compose(final double ... f) {
587 if (f.length != getOrder() + 1) {
588 throw new DimensionMismatchException(f.length, getOrder() + 1);
589 }
590 final DerivativeStructure result = new DerivativeStructure(compiler);
591 compiler.compose(data, 0, f, result.data, 0);
592 return result;
593 }
594
595
596 @Override
597 public DerivativeStructure reciprocal() {
598 final DerivativeStructure result = new DerivativeStructure(compiler);
599 compiler.pow(data, 0, -1, result.data, 0);
600 return result;
601 }
602
603
604
605
606 @Override
607 public DerivativeStructure sqrt() {
608 return rootN(2);
609 }
610
611
612
613
614 @Override
615 public DerivativeStructure cbrt() {
616 return rootN(3);
617 }
618
619
620
621
622 @Override
623 public DerivativeStructure rootN(final int n) {
624 final DerivativeStructure result = new DerivativeStructure(compiler);
625 compiler.rootN(data, 0, n, result.data, 0);
626 return result;
627 }
628
629
630 @Override
631 public Field<DerivativeStructure> getField() {
632 return new Field<DerivativeStructure>() {
633
634
635 @Override
636 public DerivativeStructure getZero() {
637 return new DerivativeStructure(compiler.getFreeParameters(), compiler.getOrder(), 0.0);
638 }
639
640
641 @Override
642 public DerivativeStructure getOne() {
643 return new DerivativeStructure(compiler.getFreeParameters(), compiler.getOrder(), 1.0);
644 }
645
646
647 @Override
648 public Class<? extends FieldElement<DerivativeStructure>> getRuntimeClass() {
649 return DerivativeStructure.class;
650 }
651 };
652 }
653
654
655
656
657
658
659
660 public static DerivativeStructure pow(final double a, final DerivativeStructure x) {
661 final DerivativeStructure result = new DerivativeStructure(x.compiler);
662 x.compiler.pow(a, x.data, 0, result.data, 0);
663 return result;
664 }
665
666
667
668
669 @Override
670 public DerivativeStructure pow(final double p) {
671 final DerivativeStructure result = new DerivativeStructure(compiler);
672 compiler.pow(data, 0, p, result.data, 0);
673 return result;
674 }
675
676
677
678
679 @Override
680 public DerivativeStructure pow(final int n) {
681 final DerivativeStructure result = new DerivativeStructure(compiler);
682 compiler.pow(data, 0, n, result.data, 0);
683 return result;
684 }
685
686
687
688
689
690
691 @Override
692 public DerivativeStructure pow(final DerivativeStructure e) {
693 compiler.checkCompatibility(e.compiler);
694 final DerivativeStructure result = new DerivativeStructure(compiler);
695 compiler.pow(data, 0, e.data, 0, result.data, 0);
696 return result;
697 }
698
699
700
701
702 @Override
703 public DerivativeStructure exp() {
704 final DerivativeStructure result = new DerivativeStructure(compiler);
705 compiler.exp(data, 0, result.data, 0);
706 return result;
707 }
708
709
710
711
712 @Override
713 public DerivativeStructure expm1() {
714 final DerivativeStructure result = new DerivativeStructure(compiler);
715 compiler.expm1(data, 0, result.data, 0);
716 return result;
717 }
718
719
720
721
722 @Override
723 public DerivativeStructure log() {
724 final DerivativeStructure result = new DerivativeStructure(compiler);
725 compiler.log(data, 0, result.data, 0);
726 return result;
727 }
728
729
730
731
732 @Override
733 public DerivativeStructure log1p() {
734 final DerivativeStructure result = new DerivativeStructure(compiler);
735 compiler.log1p(data, 0, result.data, 0);
736 return result;
737 }
738
739
740
741
742 @Override
743 public DerivativeStructure log10() {
744 final DerivativeStructure result = new DerivativeStructure(compiler);
745 compiler.log10(data, 0, result.data, 0);
746 return result;
747 }
748
749
750
751
752 @Override
753 public DerivativeStructure cos() {
754 final DerivativeStructure result = new DerivativeStructure(compiler);
755 compiler.cos(data, 0, result.data, 0);
756 return result;
757 }
758
759
760
761
762 @Override
763 public DerivativeStructure sin() {
764 final DerivativeStructure result = new DerivativeStructure(compiler);
765 compiler.sin(data, 0, result.data, 0);
766 return result;
767 }
768
769
770
771
772 @Override
773 public DerivativeStructure tan() {
774 final DerivativeStructure result = new DerivativeStructure(compiler);
775 compiler.tan(data, 0, result.data, 0);
776 return result;
777 }
778
779
780
781
782 @Override
783 public DerivativeStructure acos() {
784 final DerivativeStructure result = new DerivativeStructure(compiler);
785 compiler.acos(data, 0, result.data, 0);
786 return result;
787 }
788
789
790
791
792 @Override
793 public DerivativeStructure asin() {
794 final DerivativeStructure result = new DerivativeStructure(compiler);
795 compiler.asin(data, 0, result.data, 0);
796 return result;
797 }
798
799
800
801
802 @Override
803 public DerivativeStructure atan() {
804 final DerivativeStructure result = new DerivativeStructure(compiler);
805 compiler.atan(data, 0, result.data, 0);
806 return result;
807 }
808
809
810
811
812 @Override
813 public DerivativeStructure atan2(final DerivativeStructure x) {
814 compiler.checkCompatibility(x.compiler);
815 final DerivativeStructure result = new DerivativeStructure(compiler);
816 compiler.atan2(data, 0, x.data, 0, result.data, 0);
817 return result;
818 }
819
820
821
822
823
824
825
826
827
828 public static DerivativeStructure atan2(final DerivativeStructure y, final DerivativeStructure x) {
829 return y.atan2(x);
830 }
831
832
833
834
835 @Override
836 public DerivativeStructure cosh() {
837 final DerivativeStructure result = new DerivativeStructure(compiler);
838 compiler.cosh(data, 0, result.data, 0);
839 return result;
840 }
841
842
843
844
845 @Override
846 public DerivativeStructure sinh() {
847 final DerivativeStructure result = new DerivativeStructure(compiler);
848 compiler.sinh(data, 0, result.data, 0);
849 return result;
850 }
851
852
853
854
855 @Override
856 public DerivativeStructure tanh() {
857 final DerivativeStructure result = new DerivativeStructure(compiler);
858 compiler.tanh(data, 0, result.data, 0);
859 return result;
860 }
861
862
863
864
865 @Override
866 public DerivativeStructure acosh() {
867 final DerivativeStructure result = new DerivativeStructure(compiler);
868 compiler.acosh(data, 0, result.data, 0);
869 return result;
870 }
871
872
873
874
875 @Override
876 public DerivativeStructure asinh() {
877 final DerivativeStructure result = new DerivativeStructure(compiler);
878 compiler.asinh(data, 0, result.data, 0);
879 return result;
880 }
881
882
883
884
885 @Override
886 public DerivativeStructure atanh() {
887 final DerivativeStructure result = new DerivativeStructure(compiler);
888 compiler.atanh(data, 0, result.data, 0);
889 return result;
890 }
891
892
893
894
895 public DerivativeStructure toDegrees() {
896 final DerivativeStructure ds = new DerivativeStructure(compiler);
897 for (int i = 0; i < ds.data.length; ++i) {
898 ds.data[i] = JdkMath.toDegrees(data[i]);
899 }
900 return ds;
901 }
902
903
904
905
906 public DerivativeStructure toRadians() {
907 final DerivativeStructure ds = new DerivativeStructure(compiler);
908 for (int i = 0; i < ds.data.length; ++i) {
909 ds.data[i] = JdkMath.toRadians(data[i]);
910 }
911 return ds;
912 }
913
914
915
916
917
918
919
920 public double taylor(final double ... delta) {
921 return compiler.taylor(data, 0, delta);
922 }
923
924
925
926
927
928
929 @Override
930 public DerivativeStructure linearCombination(final DerivativeStructure[] a, final DerivativeStructure[] b) {
931
932 final double[] aDouble = new double[a.length];
933 for (int i = 0; i < a.length; ++i) {
934 aDouble[i] = a[i].getValue();
935 }
936 final double[] bDouble = new double[b.length];
937 for (int i = 0; i < b.length; ++i) {
938 bDouble[i] = b[i].getValue();
939 }
940 final double accurateValue = Sum.ofProducts(aDouble, bDouble).getAsDouble();
941
942
943 DerivativeStructure simpleValue = a[0].getField().getZero();
944 for (int i = 0; i < a.length; ++i) {
945 simpleValue = simpleValue.add(a[i].multiply(b[i]));
946 }
947
948
949 final double[] all = simpleValue.getAllDerivatives();
950 all[0] = accurateValue;
951 return new DerivativeStructure(simpleValue.getFreeParameters(), simpleValue.getOrder(), all);
952 }
953
954
955
956
957
958
959 @Override
960 public DerivativeStructure linearCombination(final double[] a, final DerivativeStructure[] b) {
961
962 final double[] bDouble = new double[b.length];
963 for (int i = 0; i < b.length; ++i) {
964 bDouble[i] = b[i].getValue();
965 }
966 final double accurateValue = Sum.ofProducts(a, bDouble).getAsDouble();
967
968
969 DerivativeStructure simpleValue = b[0].getField().getZero();
970 for (int i = 0; i < a.length; ++i) {
971 simpleValue = simpleValue.add(b[i].multiply(a[i]));
972 }
973
974
975 final double[] all = simpleValue.getAllDerivatives();
976 all[0] = accurateValue;
977 return new DerivativeStructure(simpleValue.getFreeParameters(), simpleValue.getOrder(), all);
978 }
979
980
981
982
983
984
985 @Override
986 public DerivativeStructure linearCombination(final DerivativeStructure a1, final DerivativeStructure b1,
987 final DerivativeStructure a2, final DerivativeStructure b2) {
988
989 final double accurateValue = Sum.create()
990 .addProduct(a1.getValue(), b1.getValue())
991 .addProduct(a2.getValue(), b2.getValue()).getAsDouble();
992
993
994 final DerivativeStructure simpleValue = a1.multiply(b1).add(a2.multiply(b2));
995
996
997 final double[] all = simpleValue.getAllDerivatives();
998 all[0] = accurateValue;
999 return new DerivativeStructure(getFreeParameters(), getOrder(), all);
1000 }
1001
1002
1003
1004
1005
1006
1007 @Override
1008 public DerivativeStructure linearCombination(final double a1, final DerivativeStructure b1,
1009 final double a2, final DerivativeStructure b2) {
1010
1011 final double accurateValue = Sum.create()
1012 .addProduct(a1, b1.getValue())
1013 .addProduct(a2, b2.getValue()).getAsDouble();
1014
1015
1016 final DerivativeStructure simpleValue = b1.multiply(a1).add(b2.multiply(a2));
1017
1018
1019 final double[] all = simpleValue.getAllDerivatives();
1020 all[0] = accurateValue;
1021 return new DerivativeStructure(getFreeParameters(), getOrder(), all);
1022 }
1023
1024
1025
1026
1027
1028
1029 @Override
1030 public DerivativeStructure linearCombination(final DerivativeStructure a1, final DerivativeStructure b1,
1031 final DerivativeStructure a2, final DerivativeStructure b2,
1032 final DerivativeStructure a3, final DerivativeStructure b3) {
1033
1034 final double accurateValue = Sum.create()
1035 .addProduct(a1.getValue(), b1.getValue())
1036 .addProduct(a2.getValue(), b2.getValue())
1037 .addProduct(a3.getValue(), b3.getValue()).getAsDouble();
1038
1039
1040 final DerivativeStructure simpleValue = a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3));
1041
1042
1043 final double[] all = simpleValue.getAllDerivatives();
1044 all[0] = accurateValue;
1045 return new DerivativeStructure(getFreeParameters(), getOrder(), all);
1046 }
1047
1048
1049
1050
1051
1052
1053 @Override
1054 public DerivativeStructure linearCombination(final double a1, final DerivativeStructure b1,
1055 final double a2, final DerivativeStructure b2,
1056 final double a3, final DerivativeStructure b3) {
1057
1058 final double accurateValue = Sum.create()
1059 .addProduct(a1, b1.getValue())
1060 .addProduct(a2, b2.getValue())
1061 .addProduct(a3, b3.getValue()).getAsDouble();
1062
1063
1064 final DerivativeStructure simpleValue = b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3));
1065
1066
1067 final double[] all = simpleValue.getAllDerivatives();
1068 all[0] = accurateValue;
1069 return new DerivativeStructure(getFreeParameters(), getOrder(), all);
1070 }
1071
1072
1073
1074
1075
1076
1077 @Override
1078 public DerivativeStructure linearCombination(final DerivativeStructure a1, final DerivativeStructure b1,
1079 final DerivativeStructure a2, final DerivativeStructure b2,
1080 final DerivativeStructure a3, final DerivativeStructure b3,
1081 final DerivativeStructure a4, final DerivativeStructure b4) {
1082
1083 final double accurateValue = Sum.create()
1084 .addProduct(a1.getValue(), b1.getValue())
1085 .addProduct(a2.getValue(), b2.getValue())
1086 .addProduct(a3.getValue(), b3.getValue())
1087 .addProduct(a4.getValue(), b4.getValue()).getAsDouble();
1088
1089
1090 final DerivativeStructure simpleValue = a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3)).add(a4.multiply(b4));
1091
1092
1093 final double[] all = simpleValue.getAllDerivatives();
1094 all[0] = accurateValue;
1095 return new DerivativeStructure(getFreeParameters(), getOrder(), all);
1096 }
1097
1098
1099
1100
1101
1102
1103 @Override
1104 public DerivativeStructure linearCombination(final double a1, final DerivativeStructure b1,
1105 final double a2, final DerivativeStructure b2,
1106 final double a3, final DerivativeStructure b3,
1107 final double a4, final DerivativeStructure b4) {
1108
1109 final double accurateValue = Sum.create()
1110 .addProduct(a1, b1.getValue())
1111 .addProduct(a2, b2.getValue())
1112 .addProduct(a3, b3.getValue())
1113 .addProduct(a4, b4.getValue()).getAsDouble();
1114
1115
1116 final DerivativeStructure simpleValue = b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3)).add(b4.multiply(a4));
1117
1118
1119 final double[] all = simpleValue.getAllDerivatives();
1120 all[0] = accurateValue;
1121 return new DerivativeStructure(getFreeParameters(), getOrder(), all);
1122 }
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134 @Override
1135 public boolean equals(Object other) {
1136
1137 if (this == other) {
1138 return true;
1139 }
1140
1141 if (other instanceof DerivativeStructure) {
1142 final DerivativeStructure rhs = (DerivativeStructure)other;
1143 return getFreeParameters() == rhs.getFreeParameters() &&
1144 getOrder() == rhs.getOrder() &&
1145 MathArrays.equals(data, rhs.data);
1146 }
1147
1148 return false;
1149 }
1150
1151
1152
1153
1154
1155
1156 @Override
1157 public int hashCode() {
1158 return 227 + 229 * getFreeParameters() + 233 * getOrder() + 239 * Arrays.hashCode(data);
1159 }
1160 }