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