Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
Loading...
Searching...
No Matches
arithmetic.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//arithmetic.hpp is free software: you can redistribute it and/or modify
4//it under the terms of the GNU General Public License as published by
5//the Free Software Foundation, either version 3 of the License, or
6//(at your option) any later version.
7//
8//arithmetic.hpp is distributed in the hope that it will be useful,
9//but WITHOUT ANY WARRANTY; without even the implied warranty of
10//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11//GNU General Public License for more details.
12//
13//You should have received a copy of the GNU General Public License
14//along with arithmetic.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) 2015 - 2021 by Bertini2 Development Team
17//
18// See <http://www.gnu.org/licenses/> for a copy of the license,
19// as well as COPYING. Bertini2 is provided with permitted
20// additional terms in the b2/licenses/ directory.
21
22// individual authors of this file include:
23// James Collins
24// West Texas A&M University
25// Spring, Summer 2015
26//
27// silviana amethyst, university of wisconsin-eau claire
28//
29// Created by Collins, James B. on 4/30/15.
30//
31//
32// arithmetic.hpp: Declares the arithmetic nodes for bertini2.
33
40
41#ifndef BERTINI_OPERATOR_ARITHMETIC_HPP
42#define BERTINI_OPERATOR_ARITHMETIC_HPP
43
44#include <vector>
45#include <string>
46
48
50
51
52
57
59
60#include <cmath>
61
62
63
64
65
66
67
68
69namespace bertini {
70
71namespace node{
79 class SumOperator : public virtual NaryOperator, public virtual EnableSharedFromThisVirtual<SumOperator>
80 {
81 public:
82 BERTINI_DEFAULT_VISITABLE()
83
84 virtual ~SumOperator() = default;
85
86 unsigned EliminateZeros() override;
87 unsigned EliminateOnes() override;
88 unsigned ReduceDepth() override;
89 unsigned ReduceSubSums();
90 unsigned ReduceSubMults();
91
92 template<typename... Ts>
93 static
94 std::shared_ptr<SumOperator> Make(Ts&& ...ts){
95 return std::shared_ptr<SumOperator>( new SumOperator(ts...) );
96 }
97
98 private:
99 SumOperator(const std::shared_ptr<Node> & s, bool add_or_sub)
100 {
101 AddOperand(s, add_or_sub);
102 }
103
104 SumOperator(const std::shared_ptr<Node> & left, const std::shared_ptr<Node> & right)
105 {
106 AddOperand(left);
107 AddOperand(right);
108 }
109
110
111 SumOperator(const std::shared_ptr<Node> & left, bool add_or_sub_left, const std::shared_ptr<Node> & right, bool add_or_sub_right)
112 {
113 AddOperand(left, add_or_sub_left);
114 AddOperand(right, add_or_sub_right);
115 }
116
117 public:
118
119 SumOperator& operator+=(const std::shared_ptr<Node> & rhs)
120 {
121 this->AddOperand(rhs);
122 return *this;
123 }
124
125 SumOperator& operator-=(const std::shared_ptr<Node> & rhs)
126 {
127 this->AddOperand(rhs,false);
128 return *this;
129 }
130
131
132
133
134
138 void AddOperand(std::shared_ptr<Node> child) override
139 {
140 NaryOperator::AddOperand(std::move(child));
141 signs_.push_back(true);
142 }
143
144
148 void AddOperand(std::shared_ptr<Node> child, bool sign) // not an override
149 {
150 NaryOperator::AddOperand(std::move(child));
151 signs_.push_back(sign);
152 }
153
154
158 void print(std::ostream & target) const override;
159
160
161
162
166 std::shared_ptr<Node> Differentiate(std::shared_ptr<Variable> const& v = nullptr) const override;
167
171 int Degree(std::shared_ptr<Variable> const& v = nullptr) const override;
172
173
174 int Degree(VariableGroup const& vars) const override;
175
179 std::vector<int> MultiDegree(VariableGroup const& vars) const override;
180
181 inline
182 const auto& GetSigns() const{ return this-> signs_;}
183
184
185
189 void Homogenize(VariableGroup const& vars, std::shared_ptr<Variable> const& homvar) override;
190
191 bool IsHomogeneous(std::shared_ptr<Variable> const& v = nullptr) const override;
192
196 bool IsHomogeneous(VariableGroup const& vars) const override;
197
198
199
200
201
202
203 protected:
208 dbl FreshEval_d(std::shared_ptr<Variable> const& diff_variable) const override;
209
214 void FreshEval_d(dbl& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
215
216
221 mpfr_complex FreshEval_mp(std::shared_ptr<Variable> const& diff_variable) const override;
222
227 void FreshEval_mp(mpfr_complex& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
228
229 private:
230 // Stores the sign of the particular term. There is a one-one
231 // correspondence between elements of signs_ and operand_. This
232 // is enforced by the AddOperand method below, redefined in SumOperator.
233
234 // TODO(JBC): If we add method to delete child, must also delete signs_ entry.
235 std::vector<bool> signs_;
236
237 private:
238
239 SumOperator() = default;
240
241 friend class boost::serialization::access;
242
243 template <typename Archive>
244 void serialize(Archive& ar, const unsigned version) {
245 ar & boost::serialization::base_object<NaryOperator>(*this);
246 ar & signs_;
247 }
248
249
250 void PrecisionChangeSpecific(unsigned prec) const override
251 {
252 temp_mp_.precision(prec);
253 }
254
255 mutable mpfr_complex temp_mp_;
256 mutable dbl temp_d_;
257
258 friend MultOperator;
259 };
260
261
262
263
264
265
266
267
268
269
270
271
272
273
280 class NegateOperator : public virtual UnaryOperator, public virtual EnableSharedFromThisVirtual<NegateOperator>
281 {
282 public:
283 BERTINI_DEFAULT_VISITABLE()
284
285 template<typename... Ts>
286 static
287 std::shared_ptr<NegateOperator> Make(Ts&& ...ts){
288 return std::shared_ptr<NegateOperator>( new NegateOperator(ts...) );
289 }
290
291 private:
292
293 NegateOperator(const std::shared_ptr<Node> & N) : UnaryOperator(N)
294 {};
295
296 public:
297
298 unsigned EliminateZeros() override;
299 unsigned EliminateOnes() override;
300
304 void print(std::ostream & target) const override;
305
306
310 std::shared_ptr<Node> Differentiate(std::shared_ptr<Variable> const& v = nullptr) const override;
311
312 bool IsHomogeneous(std::shared_ptr<Variable> const& v = nullptr) const override
313 {
314 return operand_->IsHomogeneous(v);
315 }
316
320 bool IsHomogeneous(VariableGroup const& vars) const override
321 {
322 return operand_->IsHomogeneous(vars);
323 }
324
325 virtual ~NegateOperator() = default;
326
327 protected:
328
329 // Specific implementation of FreshEval for negate.
330 dbl FreshEval_d(std::shared_ptr<Variable> const& diff_variable) const override;
331 void FreshEval_d(dbl& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
332
333 mpfr_complex FreshEval_mp(std::shared_ptr<Variable> const& diff_variable) const override;
334 void FreshEval_mp(mpfr_complex& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
335
336
337 private:
338
339 NegateOperator() = default;
340
341 friend class boost::serialization::access;
342
343 template <typename Archive>
344 void serialize(Archive& ar, const unsigned version) {
345 ar & boost::serialization::base_object<UnaryOperator>(*this);
346 }
347 };
348
349
350 inline std::shared_ptr<Node> operator-(const std::shared_ptr<Node> & rhs)
351 {
352 return NegateOperator::Make(rhs);
353 }
354
355
356
357
358
359
360
361
362
363
364
371 class MultOperator : public virtual NaryOperator, public virtual EnableSharedFromThisVirtual<MultOperator>
372 {
373 public:
374 BERTINI_DEFAULT_VISITABLE()
375
376 unsigned EliminateZeros() override;
377 unsigned EliminateOnes() override;
378 unsigned ReduceDepth() override;
379 unsigned ReduceSubSums();
380 unsigned ReduceSubMults();
381
382
383 template<typename... Ts>
384 static
385 std::shared_ptr<MultOperator> Make(Ts&& ...ts){
386 return std::shared_ptr<MultOperator>( new MultOperator(ts...) );
387 }
388
389 private:
395 MultOperator(std::shared_ptr<Node> const& s)
396 {
397 AddOperand(s);
398 }
399
400 MultOperator(std::shared_ptr<Node> const& left, std::shared_ptr<Node> const& right)
401 {
402 AddOperand(left);
403 AddOperand(right);
404 }
405
406
407 MultOperator(const std::shared_ptr<Node> & left, bool mult_or_div_left, const std::shared_ptr<Node> & right, bool mult_or_div_right)
408 {
409 AddOperand(left, mult_or_div_left);
410 AddOperand(right, mult_or_div_right);
411 }
412
413 public:
414
415 virtual ~MultOperator() = default;
416
417
418
419
420 //Special Behaviour: by default all factors are in numerator
421 void AddOperand(std::shared_ptr<Node> child) override
422 {
423 NaryOperator::AddOperand(std::move(child));
424 mult_or_div_.push_back(true);
425 }
426
427
428
429 //Special Behaviour: Pass bool to set sign of term: true = mult, false = divide
430 void AddOperand(std::shared_ptr<Node> child, bool mult) // not an override
431 {
432 NaryOperator::AddOperand(std::move(child));
433 mult_or_div_.push_back(mult);
434 }
435
436
440 void print(std::ostream & target) const override;
441
445 std::shared_ptr<Node> Differentiate(std::shared_ptr<Variable> const& v = nullptr) const override;
446
450 int Degree(std::shared_ptr<Variable> const& v = nullptr) const override;
451
452
453 int Degree(VariableGroup const& vars) const override;
454
458 std::vector<int> MultiDegree(VariableGroup const& vars) const override;
459
460
461 void Homogenize(VariableGroup const& vars, std::shared_ptr<Variable> const& homvar) override;
462
463 bool IsHomogeneous(std::shared_ptr<Variable> const& v = nullptr) const override;
464
468 bool IsHomogeneous(VariableGroup const& vars) const override;
469
475 inline
476 const auto& GetMultOrDiv() const{ return this->mult_or_div_;}
477
478 protected:
479
480 // Specific implementation of FreshEval for mult and divide.
481 // If child_mult_ = true, then multiply, else divide
482 dbl FreshEval_d(std::shared_ptr<Variable> const& diff_variable) const override;
483 void FreshEval_d(dbl& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
484
485 mpfr_complex FreshEval_mp(std::shared_ptr<Variable> const& diff_variable) const override;
486 void FreshEval_mp(mpfr_complex& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
487
488
489
490
491
492
493 private:
494
495 MultOperator() = default;
496
497 // Stores the mult/div of a factor. There is a one-one
498 // correspondence between elements of signs_ and operand_. This
499 // is enforced by the AddOperand method, redefined in MultOperator.
500
501 // TODO(JBC): If we add method to delete child, must also delete children_mult_ entry.
502 std::vector<bool> mult_or_div_;
503
504
505 private:
506
507 friend class boost::serialization::access;
508
509 template <typename Archive>
510 void serialize(Archive& ar, const unsigned version) {
511 ar & boost::serialization::base_object<NaryOperator>(*this);
512 ar & mult_or_div_;
513 }
514
515 void PrecisionChangeSpecific(unsigned prec) const override
516 {
517 temp_mp_.precision(prec);
518 }
519
520 mutable mpfr_complex temp_mp_;
521 mutable dbl temp_d_;
522
523 friend SumOperator;
524 };
525
526
527
528
529
538 class PowerOperator : public virtual Operator, public virtual EnableSharedFromThisVirtual<PowerOperator>
539 {
540
541 public:
542 BERTINI_DEFAULT_VISITABLE()
543
544 unsigned EliminateZeros() override;
545 unsigned EliminateOnes() override;
546
547 template<typename... Ts>
548 static
549 std::shared_ptr<PowerOperator> Make(Ts&& ...ts){
550 return std::shared_ptr<PowerOperator>( new PowerOperator(ts...) );
551 }
552
553
554 private:
555 PowerOperator(const std::shared_ptr<Node> & new_base, const std::shared_ptr<Node> & new_exponent) : base_(new_base), exponent_(new_exponent)
556 {
557 }
558
559 public:
560
561
562
563 void SetBase(std::shared_ptr<Node> new_base)
564 {
565 base_ = new_base;
566 }
567
568 void SetExponent(std::shared_ptr<Node> new_exponent)
569 {
570 exponent_ = new_exponent;
571 }
572
573 std::shared_ptr<Node> GetBase() const
574 {
575 return base_;
576 }
577
578 std::shared_ptr<Node> GetExponent() const
579 {
580 return exponent_;
581 }
582
583 void Reset() const override;
584
585
586
587 void print(std::ostream & target) const override;
588
589
590
594 std::shared_ptr<Node> Differentiate(std::shared_ptr<Variable> const& v = nullptr) const override;
595
599 int Degree(std::shared_ptr<Variable> const& v = nullptr) const override;
600
601 int Degree(VariableGroup const& vars) const override;
602
606 std::vector<int> MultiDegree(VariableGroup const& vars) const override;
607
608
609
610 void Homogenize(VariableGroup const& vars, std::shared_ptr<Variable> const& homvar) override;
611
612 bool IsHomogeneous(std::shared_ptr<Variable> const& v = nullptr) const override;
613
617 bool IsHomogeneous(VariableGroup const& vars) const override;
618
619 virtual ~PowerOperator() = default;
620
626 virtual void precision(unsigned int prec) const override
627 {
628 auto& val_pair = std::get< std::pair<mpfr_complex,bool> >(current_value_);
629 val_pair.first.precision(prec);
630
631 base_->precision(prec);
632 exponent_->precision(prec);
633 }
634
635
636
637 protected:
638
639 dbl FreshEval_d(std::shared_ptr<Variable> const& diff_variable) const override;
640 void FreshEval_d(dbl& evaulation_value, std::shared_ptr<Variable> const& diff_variable) const override;
641
642 mpfr_complex FreshEval_mp(std::shared_ptr<Variable> const& diff_variable) const override;
643 void FreshEval_mp(mpfr_complex& evaulation_value, std::shared_ptr<Variable> const& diff_variable) const override;
644
645 private:
646
647 PowerOperator() = default;
648
649 std::shared_ptr<Node> base_;
650 std::shared_ptr<Node> exponent_;
651
652
653
654 private:
655
656 friend class boost::serialization::access;
657
658
659 template <typename Archive>
660 void serialize(Archive& ar, const unsigned version) {
661 ar & boost::serialization::base_object<Operator>(*this);
662 ar & base_;
663 ar & exponent_;
664 }
665 };
666 // end of the class PowerOperator
667
668
669
670
671
672
673
674
675
676
677
678
679
680
689 class IntegerPowerOperator : public virtual UnaryOperator, public virtual EnableSharedFromThisVirtual<IntegerPowerOperator>
690 {
691 public:
692 BERTINI_DEFAULT_VISITABLE()
693
694 unsigned EliminateZeros() override;
695 unsigned EliminateOnes() override;
696
700 void print(std::ostream & target) const override;
701
702
706 void set_exponent(int exp)
707 {
708 exponent_ = exp;
709 }
710
711
715 int exponent() const
716 {
717 return exponent_;
718 }
719
720
724 std::shared_ptr<Node> Differentiate(std::shared_ptr<Variable> const& v = nullptr) const override;
725
729 int Degree(std::shared_ptr<Variable> const& v = nullptr) const override;
730
731
732 bool IsHomogeneous(std::shared_ptr<Variable> const& v = nullptr) const override
733 {
734 return operand_->IsHomogeneous(v);
735 }
736
737
741 bool IsHomogeneous(VariableGroup const& vars) const override
742 {
743 return operand_->IsHomogeneous(vars);
744 }
745
746
747 virtual ~IntegerPowerOperator() = default;
748
749
750 template<typename... Ts>
751 static
752 std::shared_ptr<IntegerPowerOperator> Make(Ts&& ...ts){
753 return std::shared_ptr<IntegerPowerOperator>( new IntegerPowerOperator(ts...) );
754 }
755
756 private:
760 IntegerPowerOperator(const std::shared_ptr<Node> & N, int p) : exponent_(p), UnaryOperator(N)
761 {}
762
763
764
765
766 protected:
767
768
769 dbl FreshEval_d(std::shared_ptr<Variable> const& diff_variable) const override
770 {
771 return pow(operand_->Eval<dbl>(diff_variable), exponent_);
772 }
773
774 void FreshEval_d(dbl& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override
775 {
776 operand_->EvalInPlace<dbl>(evaluation_value, diff_variable);
777 evaluation_value = pow(evaluation_value, exponent_);
778 }
779
780
781 mpfr_complex FreshEval_mp(std::shared_ptr<Variable> const& diff_variable) const override
782 {
783 return pow(operand_->Eval<mpfr_complex>(diff_variable),exponent_);
784 }
785
786 void FreshEval_mp(mpfr_complex& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override
787 {
788 operand_->EvalInPlace<mpfr_complex>(evaluation_value, diff_variable);
789 evaluation_value = pow(evaluation_value, exponent_);
790 }
791
792 private:
793
794 IntegerPowerOperator() = default;
795
796
797 int exponent_;
798
799 friend class boost::serialization::access;
800
801 template <typename Archive>
802 void serialize(Archive& ar, const unsigned version) {
803 ar & boost::serialization::base_object<UnaryOperator>(*this);
804 ar & exponent_;
805 }
806 }; // re: class IntegerPowerOperator
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
834 class SqrtOperator : public virtual UnaryOperator, public virtual EnableSharedFromThisVirtual<SqrtOperator>
835 {
836 public:
837 BERTINI_DEFAULT_VISITABLE()
838
839 template<typename... Ts>
840 static
841 std::shared_ptr<SqrtOperator> Make(Ts&& ...ts){
842 return std::shared_ptr<SqrtOperator>( new SqrtOperator(ts...) );
843 }
844
845 private:
846 SqrtOperator(const std::shared_ptr<Node> & N) : UnaryOperator(N)
847 {};
848
849 public:
850
851 unsigned EliminateZeros() override;
852 unsigned EliminateOnes() override;
853
854 void print(std::ostream & target) const override;
855
856
860 std::shared_ptr<Node> Differentiate(std::shared_ptr<Variable> const& v = nullptr) const override;
861
867 int Degree(std::shared_ptr<Variable> const& v = nullptr) const override;
868
869
870 virtual ~SqrtOperator() = default;
871
872 protected:
873
874 // Specific implementation of FreshEval for negate.
875 dbl FreshEval_d(std::shared_ptr<Variable> const& diff_variable) const override;
876 void FreshEval_d(dbl& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
877
878 mpfr_complex FreshEval_mp(std::shared_ptr<Variable> const& diff_variable) const override;
879 void FreshEval_mp(mpfr_complex& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
880
881
882 private:
883
884 SqrtOperator() = default;
885
886 friend class boost::serialization::access;
887
888 template <typename Archive>
889 void serialize(Archive& ar, const unsigned version) {
890 ar & boost::serialization::base_object<UnaryOperator>(*this);
891 }
892 };
893
894
895
896 inline std::shared_ptr<Node> sqrt(const std::shared_ptr<Node> & N)
897 {
898 return SqrtOperator::Make(N);
899 }
900
901
902
903
910 class ExpOperator : public virtual UnaryOperator, public virtual EnableSharedFromThisVirtual<ExpOperator>
911 {
912 public:
913 BERTINI_DEFAULT_VISITABLE()
914
915 unsigned EliminateZeros() override;
916 unsigned EliminateOnes() override;
917
918 template<typename... Ts>
919 static
920 std::shared_ptr<ExpOperator> Make(Ts&& ...ts){
921 return std::shared_ptr<ExpOperator>( new ExpOperator(ts...) );
922 }
923
924 private:
925 ExpOperator(const std::shared_ptr<Node> & N) : UnaryOperator(N)
926 {};
927
928 public:
929
930
931
932
933 void print(std::ostream & target) const override;
934
935
939 std::shared_ptr<Node> Differentiate(std::shared_ptr<Variable> const& v = nullptr) const override;
940
946 int Degree(std::shared_ptr<Variable> const& v = nullptr) const override;
947
948
949 virtual ~ExpOperator() = default;
950
951 protected:
952
953 // Specific implementation of FreshEval for exponentiate.
954 dbl FreshEval_d(std::shared_ptr<Variable> const& diff_variable) const override;
955 void FreshEval_d(dbl& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
956
957 mpfr_complex FreshEval_mp(std::shared_ptr<Variable> const& diff_variable) const override;
958 void FreshEval_mp(mpfr_complex& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
959
960 private:
961 ExpOperator() = default;
962 friend class boost::serialization::access;
963
964 template <typename Archive>
965 void serialize(Archive& ar, const unsigned version) {
966 ar & boost::serialization::base_object<UnaryOperator>(*this);
967 }
968 };
969
970
976 class LogOperator : public virtual UnaryOperator, public virtual EnableSharedFromThisVirtual<LogOperator>
977 {
978 public:
979 BERTINI_DEFAULT_VISITABLE()
980
981 unsigned EliminateZeros() override;
982 unsigned EliminateOnes() override;
983
984 template<typename... Ts>
985 static
986 std::shared_ptr<LogOperator> Make(Ts&& ...ts){
987 return std::shared_ptr<LogOperator>( new LogOperator(ts...) );
988 }
989
990 private:
991 LogOperator(const std::shared_ptr<Node> & N) : UnaryOperator(N)
992 {};
993
994 public:
995
996
997
998
999 void print(std::ostream & target) const override;
1000
1001
1005 std::shared_ptr<Node> Differentiate(std::shared_ptr<Variable> const& v = nullptr) const override;
1006
1012 int Degree(std::shared_ptr<Variable> const& v = nullptr) const override;
1013
1014
1015 virtual ~LogOperator() = default;
1016
1017 protected:
1018
1019 // Specific implementation of FreshEval for exponentiate.
1020 dbl FreshEval_d(std::shared_ptr<Variable> const& diff_variable) const override;
1021 void FreshEval_d(dbl& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
1022
1023 mpfr_complex FreshEval_mp(std::shared_ptr<Variable> const& diff_variable) const override;
1024 void FreshEval_mp(mpfr_complex& evaluation_value, std::shared_ptr<Variable> const& diff_variable) const override;
1025
1026 private:
1027 LogOperator() = default;
1028 friend class boost::serialization::access;
1029
1030 template <typename Archive>
1031 void serialize(Archive& ar, const unsigned version) {
1032 ar & boost::serialization::base_object<UnaryOperator>(*this);
1033 }
1034 };
1035
1036
1037
1038
1039 // begin the overload of operators
1040
1041 inline std::shared_ptr<Node> exp(const std::shared_ptr<Node> & N)
1042 {
1043 return ExpOperator::Make(N);
1044 }
1045
1046 inline std::shared_ptr<Node> log(const std::shared_ptr<Node> & N)
1047 {
1048 return LogOperator::Make(N);
1049 }
1050
1051 inline std::shared_ptr<Node> pow(const std::shared_ptr<Node> & N, const std::shared_ptr<Node> & p)
1052 {
1053 return PowerOperator::Make(N,p);
1054 }
1055
1056 inline std::shared_ptr<Node> pow(std::shared_ptr<Node> const& base, int power)
1057 {
1058 return IntegerPowerOperator::Make(base,power);
1059 }
1060
1061 std::shared_ptr<Node> pow(const std::shared_ptr<Node> & N, double p) = delete;
1062
1063 std::shared_ptr<Node> pow(const std::shared_ptr<Node> & N, dbl p) = delete;
1064
1065 inline std::shared_ptr<Node> pow(const std::shared_ptr<Node> & N, mpfr_float p)
1066 {
1067 return PowerOperator::Make(N,Float::Make(p));
1068 }
1069
1070 inline std::shared_ptr<Node> pow(const std::shared_ptr<Node> & N, mpfr_complex p)
1071 {
1072 return PowerOperator::Make(N,Float::Make(p));
1073 }
1074
1075 inline std::shared_ptr<Node> pow(const std::shared_ptr<Node> & N, mpq_rational const& p)
1076 {
1077 return PowerOperator::Make(N,Rational::Make(p,0));
1078 }
1079
1080
1081
1082
1083
1084
1086 //
1087 // SUM AND DIFFERENCE ARITHMETIC OPERATORS
1088 //
1090
1091
1092
1094 //
1095 // addition operators
1096 //
1098
1099
1100 inline std::shared_ptr<Node>& operator+=(std::shared_ptr<Node> & lhs, const std::shared_ptr<Node> & rhs)
1101 {
1102 std::shared_ptr<Node> temp = SumOperator::Make(lhs,rhs);
1103 lhs.swap(temp);
1104 return lhs;
1105 }
1106
1107
1108
1109
1110
1111 inline std::shared_ptr<Node> operator+(std::shared_ptr<Node> lhs, const std::shared_ptr<Node> & rhs)
1112 {
1113 return SumOperator::Make(lhs,rhs);
1114 }
1115
1116 inline std::shared_ptr<Node> operator+(std::shared_ptr<Node> lhs, mpfr_float const& rhs)
1117 {
1118 return SumOperator::Make(lhs,Float::Make(rhs));
1119 }
1120
1121 inline std::shared_ptr<Node> operator+(std::shared_ptr<Node> lhs, mpfr_complex const& rhs)
1122 {
1123 return SumOperator::Make(lhs,Float::Make(rhs));
1124 }
1125
1126 inline std::shared_ptr<Node> operator+(mpfr_float const& lhs, std::shared_ptr<Node> rhs)
1127 {
1128 return SumOperator::Make(Float::Make(lhs), rhs);
1129 }
1130
1131 inline std::shared_ptr<Node> operator+(mpfr_complex const& lhs, std::shared_ptr<Node> rhs)
1132 {
1133 return SumOperator::Make(Float::Make(lhs), rhs);
1134 }
1135
1136 inline std::shared_ptr<Node> operator+(std::shared_ptr<Node> lhs, int rhs)
1137 {
1138 return SumOperator::Make(lhs,Integer::Make(rhs));
1139 }
1140
1141 inline std::shared_ptr<Node> operator+(int lhs, std::shared_ptr<Node> rhs)
1142 {
1143 return SumOperator::Make(Integer::Make(lhs), rhs);
1144 }
1145
1146 inline std::shared_ptr<Node> operator+(std::shared_ptr<Node> lhs, mpz_int const& rhs)
1147 {
1148 return SumOperator::Make(lhs,Integer::Make(rhs));
1149 }
1150
1151 inline std::shared_ptr<Node> operator+(mpz_int const& lhs, std::shared_ptr<Node> rhs)
1152 {
1153 return SumOperator::Make(Integer::Make(lhs), rhs);
1154 }
1155
1156 inline std::shared_ptr<Node> operator+(std::shared_ptr<Node> lhs, mpq_rational const& rhs)
1157 {
1158 return SumOperator::Make(lhs,Rational::Make(rhs,0));
1159 }
1160
1161 inline std::shared_ptr<Node> operator+(mpq_rational const& lhs, std::shared_ptr<Node> rhs)
1162 {
1163 return SumOperator::Make(Rational::Make(lhs,0), rhs);
1164 }
1165
1166
1167
1169 //
1170 // subtraction operators
1171 //
1173
1174
1175 inline std::shared_ptr<Node>& operator-=(std::shared_ptr<Node> & lhs, const std::shared_ptr<Node> & rhs)
1176 {
1177 std::shared_ptr<Node> temp = SumOperator::Make(lhs,true,rhs,false);
1178 lhs.swap(temp);
1179 return lhs;
1180 }
1181
1182
1183 inline std::shared_ptr<Node> operator-(std::shared_ptr<Node> lhs, const std::shared_ptr<Node> & rhs)
1184 {
1185 return SumOperator::Make(lhs,true,rhs,false);
1186 }
1187
1188 inline std::shared_ptr<Node> operator-(std::shared_ptr<Node> lhs, mpfr_float rhs)
1189 {
1190 return SumOperator::Make(lhs, true, Float::Make(rhs), false);
1191 }
1192
1193 inline std::shared_ptr<Node> operator-(mpfr_float lhs, std::shared_ptr<Node> rhs)
1194 {
1195 return SumOperator::Make(Float::Make(lhs), true, rhs, false);
1196 }
1197
1198 inline std::shared_ptr<Node> operator-(std::shared_ptr<Node> lhs, mpfr_complex rhs)
1199 {
1200 return SumOperator::Make(lhs, true, Float::Make(rhs), false);
1201 }
1202
1203 inline std::shared_ptr<Node> operator-(mpfr_complex lhs, std::shared_ptr<Node> rhs)
1204 {
1205 return SumOperator::Make(Float::Make(lhs), true, rhs, false);
1206 }
1207
1208 inline std::shared_ptr<Node> operator-(std::shared_ptr<Node> lhs, int rhs)
1209 {
1210 return SumOperator::Make(lhs, true, Integer::Make(rhs), false);
1211 }
1212
1213 inline std::shared_ptr<Node> operator-(int lhs, std::shared_ptr<Node> rhs)
1214 {
1215 return SumOperator::Make(Integer::Make(lhs), true, rhs, false);
1216 }
1217
1218 inline std::shared_ptr<Node> operator-(std::shared_ptr<Node> lhs, mpz_int const& rhs)
1219 {
1220 return SumOperator::Make(lhs, true, Integer::Make(rhs), false);
1221 }
1222
1223 inline std::shared_ptr<Node> operator-(mpz_int const& lhs, std::shared_ptr<Node> rhs)
1224 {
1225 return SumOperator::Make(Integer::Make(lhs), true, rhs, false);
1226 }
1227
1228 inline std::shared_ptr<Node> operator-(std::shared_ptr<Node> lhs, mpq_rational const& rhs)
1229 {
1230 return SumOperator::Make(lhs, true, Rational::Make(rhs,0), false);
1231 }
1232
1233 inline std::shared_ptr<Node> operator-(mpq_rational const& lhs, std::shared_ptr<Node> rhs)
1234 {
1235 return SumOperator::Make(Rational::Make(lhs,0), true, rhs, false);
1236 }
1237
1238
1239
1240 /*
1241 multiplication operators
1242 */
1243 inline std::shared_ptr<Node> operator*=(std::shared_ptr<MultOperator> & lhs, const std::shared_ptr<Node> & rhs)
1244 {
1245 lhs->AddOperand(rhs);
1246 return lhs;
1247 }
1248
1249
1250 inline std::shared_ptr<Node> operator*(std::shared_ptr<Node> lhs, mpfr_float rhs)
1251 {
1252 return MultOperator::Make(lhs,Float::Make(rhs));
1253 }
1254
1255 inline std::shared_ptr<Node> operator*(std::shared_ptr<Node> lhs, mpfr_complex rhs)
1256 {
1257 return MultOperator::Make(lhs,Float::Make(rhs));
1258 }
1259
1260 inline std::shared_ptr<Node> operator*(mpfr_float lhs, std::shared_ptr<Node> rhs)
1261 {
1262 return MultOperator::Make(Float::Make(lhs), rhs);
1263 }
1264
1265 inline std::shared_ptr<Node> operator*(mpfr_complex lhs, std::shared_ptr<Node> rhs)
1266 {
1267 return MultOperator::Make(Float::Make(lhs), rhs);
1268 }
1269
1270 inline std::shared_ptr<Node> operator*(std::shared_ptr<Node> lhs, int rhs)
1271 {
1272 return MultOperator::Make(lhs,Integer::Make(rhs));
1273 }
1274
1275 inline std::shared_ptr<Node> operator*(int lhs, std::shared_ptr<Node> rhs)
1276 {
1277 return MultOperator::Make(Integer::Make(lhs), rhs);
1278 }
1279
1280 inline std::shared_ptr<Node> operator*(std::shared_ptr<Node> lhs, mpz_int const& rhs)
1281 {
1282 return MultOperator::Make(lhs,Integer::Make(rhs));
1283 }
1284
1285 inline std::shared_ptr<Node> operator*(mpz_int const& lhs, std::shared_ptr<Node> rhs)
1286 {
1287 return MultOperator::Make(Integer::Make(lhs), rhs);
1288 }
1289
1290 inline std::shared_ptr<Node> operator*(std::shared_ptr<Node> lhs, mpq_rational const& rhs)
1291 {
1292 return MultOperator::Make(lhs,Rational::Make(rhs,0));
1293 }
1294
1295 inline std::shared_ptr<Node> operator*(mpq_rational const& lhs, std::shared_ptr<Node> rhs)
1296 {
1297 return MultOperator::Make(Rational::Make(lhs,0), rhs);
1298 }
1299
1300
1301 // this function provides an optimization for combining two power operators with the same base.
1302 inline std::shared_ptr<Node>& operator*=(std::shared_ptr<Node> & lhs, const std::shared_ptr<Node> & rhs)
1303 {
1304
1305 // if the two nodes are integer power operators, and if they point the same place, then add the powers.
1306
1307 if (std::dynamic_pointer_cast<IntegerPowerOperator>(lhs) && std::dynamic_pointer_cast<IntegerPowerOperator>(rhs))
1308 {
1309
1310 auto lhs_as_intpow = std::dynamic_pointer_cast<IntegerPowerOperator>(lhs); // ugh, doing this cast twice?!?!? fix this.
1311 auto rhs_as_intpow = std::dynamic_pointer_cast<IntegerPowerOperator>(rhs);
1312
1313 if (lhs_as_intpow->Operand()==rhs_as_intpow->Operand())
1314 {
1315 if (lhs_as_intpow->exponent()>=0 && rhs_as_intpow->exponent()>=0)
1316 {
1317 std::shared_ptr<Node> temp = pow(lhs_as_intpow->Operand(),lhs_as_intpow->exponent() + rhs_as_intpow->exponent());
1318 lhs.swap(temp);
1319 return lhs;
1320 }
1321 }
1322 }
1323
1324 std::shared_ptr<Node> temp = MultOperator::Make(lhs,rhs);
1325 lhs.swap(temp);
1326 return lhs;
1327
1328 }
1329
1330 inline std::shared_ptr<Node> operator*(std::shared_ptr<Node> lhs, const std::shared_ptr<Node> & rhs)
1331 {
1332 return lhs*=rhs;
1333 }
1334
1335
1336
1337
1338
1339
1340 /*
1341 division operators
1342 */
1343
1344
1345 inline std::shared_ptr<Node>& operator/=(std::shared_ptr<Node> & lhs, const std::shared_ptr<Node> & rhs)
1346 {
1347
1348 // if (std::dynamic_pointer_cast<IntegerPowerOperator>(lhs) && std::dynamic_pointer_cast<IntegerPowerOperator>(rhs))
1349 // {
1350
1351 // auto lhs_as_intpow = std::dynamic_pointer_cast<IntegerPowerOperator>(lhs);
1352 // auto rhs_as_intpow = std::dynamic_pointer_cast<IntegerPowerOperator>(rhs);
1353 // if (lhs_as_intpow->first_child()==rhs_as_intpow->first_child())
1354 // {
1355 // std::shared_ptr<Node> temp = pow(lhs_as_intpow->first_child(),lhs_as_intpow->exponent() - rhs_as_intpow->exponent());
1356 // lhs.swap(temp);
1357 // return lhs;
1358 // }
1359 // }
1360
1361
1362 std::shared_ptr<Node> temp = MultOperator::Make(lhs,true,rhs,false);
1363 lhs.swap(temp);
1364 return lhs;
1365 }
1366
1367 inline std::shared_ptr<Node> operator/=(std::shared_ptr<MultOperator> & lhs, const std::shared_ptr<Node> & rhs)
1368 {
1369 lhs->AddOperand(rhs,false);
1370 return lhs;
1371 }
1372
1373
1374
1375 inline std::shared_ptr<Node> operator/(std::shared_ptr<Node> lhs, const std::shared_ptr<Node> & rhs)
1376 {
1377 return lhs/=rhs;
1378 }
1379
1380 inline std::shared_ptr<Node> operator/(std::shared_ptr<Node> lhs, mpfr_float rhs)
1381 {
1382 return MultOperator::Make(lhs, true, Float::Make(rhs), false);
1383 }
1384
1385 inline std::shared_ptr<Node> operator/(std::shared_ptr<Node> lhs, mpfr_complex rhs)
1386 {
1387 return MultOperator::Make(lhs, true, Float::Make(rhs), false);
1388 }
1389
1390 inline std::shared_ptr<Node> operator/(mpfr_float lhs, std::shared_ptr<Node> rhs)
1391 {
1392 return MultOperator::Make(Float::Make(lhs), true, rhs, false);
1393 }
1394
1395 inline std::shared_ptr<Node> operator/(mpfr_complex lhs, std::shared_ptr<Node> rhs)
1396 {
1397 return MultOperator::Make(Float::Make(lhs), true, rhs, false);
1398 }
1399
1400 inline std::shared_ptr<Node> operator/(std::shared_ptr<Node> lhs, int rhs)
1401 {
1402 return MultOperator::Make(lhs, true, Integer::Make(rhs), false);
1403 }
1404
1405 inline std::shared_ptr<Node> operator/(int lhs, std::shared_ptr<Node> rhs)
1406 {
1407 return MultOperator::Make(Integer::Make(lhs), true, rhs, false);
1408 }
1409
1410 inline std::shared_ptr<Node> operator/(std::shared_ptr<Node> lhs, mpz_int const& rhs)
1411 {
1412 return MultOperator::Make(lhs, true, Integer::Make(rhs), false);
1413 }
1414
1415 inline std::shared_ptr<Node> operator/(mpz_int const& lhs, std::shared_ptr<Node> rhs)
1416 {
1417 return MultOperator::Make(Integer::Make(lhs), true, rhs, false);
1418 }
1419
1420 inline std::shared_ptr<Node> operator/(std::shared_ptr<Node> lhs, mpq_rational const& rhs)
1421 {
1422 return MultOperator::Make(lhs, true, Rational::Make(rhs,0), false);
1423 }
1424
1425 inline std::shared_ptr<Node> operator/(mpq_rational const& lhs, std::shared_ptr<Node> rhs)
1426 {
1427 return MultOperator::Make(Rational::Make(lhs,0), true, rhs, false);
1428 }
1429
1430
1431
1432} // re: namespace node
1433} // re: namespace bertini
1434
1435
1436
1437
1438
1439
1440#endif
unsigned EliminateOnes() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:1279
int Degree(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:1300
mpfr_complex FreshEval_mp(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:1324
void print(std::ostream &target) const override
Definition arithmetic.cpp:1284
dbl FreshEval_d(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:1312
std::shared_ptr< Node > Differentiate(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:1294
This class represents the exponentiation Operator.
Definition arithmetic.hpp:690
bool IsHomogeneous(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.hpp:732
bool IsHomogeneous(VariableGroup const &vars) const override
Definition arithmetic.hpp:741
void print(std::ostream &target) const override
Definition arithmetic.cpp:1137
int Degree(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:1166
void FreshEval_d(dbl &evaluation_value, std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.hpp:774
std::shared_ptr< Node > Differentiate(std::shared_ptr< Variable > const &v=nullptr) const override
Differentiate.
Definition arithmetic.cpp:1146
int exponent() const
Definition arithmetic.hpp:715
void FreshEval_mp(mpfr_complex &evaluation_value, std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.hpp:786
mpfr_complex FreshEval_mp(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.hpp:781
void set_exponent(int exp)
Definition arithmetic.hpp:706
dbl FreshEval_d(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.hpp:769
unsigned EliminateOnes() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:1132
std::shared_ptr< Node > Differentiate(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:1369
mpfr_complex FreshEval_mp(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:1399
void print(std::ostream &target) const override
Definition arithmetic.cpp:1360
dbl FreshEval_d(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:1387
unsigned EliminateOnes() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:1355
int Degree(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:1375
Multiplication and division Operator.
Definition arithmetic.hpp:372
const auto & GetMultOrDiv() const
Definition arithmetic.hpp:476
void print(std::ostream &target) const override
Definition arithmetic.cpp:692
void Homogenize(VariableGroup const &vars, std::shared_ptr< Variable > const &homvar) override
Definition arithmetic.cpp:832
mpfr_complex FreshEval_mp(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:894
int Degree(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:763
std::vector< int > MultiDegree(VariableGroup const &vars) const override
Definition arithmetic.cpp:815
std::shared_ptr< Node > Differentiate(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:716
unsigned ReduceDepth() override
A mutating function which finds ways to reduce the depth of the tree.
Definition arithmetic.cpp:680
unsigned EliminateOnes() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:567
dbl FreshEval_d(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:867
bool IsHomogeneous(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:841
The negation Operator.
Definition arithmetic.hpp:281
bool IsHomogeneous(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.hpp:312
unsigned EliminateOnes() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:462
dbl FreshEval_d(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:479
bool IsHomogeneous(VariableGroup const &vars) const override
Definition arithmetic.hpp:320
std::shared_ptr< Node > Differentiate(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:474
void print(std::ostream &target) const override
Definition arithmetic.cpp:467
unsigned EliminateZeros() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:458
mpfr_complex FreshEval_mp(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:491
virtual unsigned EliminateZeros()=0
A transform function, which eliminates nodes from the tree.
Abstract Node type from which all Operators inherit.
Definition operator.hpp:58
Operator for power functions with arbitrary expressions in the exponent and base.
Definition arithmetic.hpp:539
bool IsHomogeneous(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:1049
void Reset() const override
Definition arithmetic.cpp:941
dbl FreshEval_d(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:1078
std::vector< int > MultiDegree(VariableGroup const &vars) const override
Definition arithmetic.cpp:1025
virtual void precision(unsigned int prec) const override
Definition arithmetic.hpp:626
void Homogenize(VariableGroup const &vars, std::shared_ptr< Variable > const &homvar) override
Definition arithmetic.cpp:1037
mpfr_complex FreshEval_mp(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:1093
int Degree(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:965
std::shared_ptr< Node > Differentiate(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:954
void print(std::ostream &target) const override
Definition arithmetic.cpp:948
unsigned EliminateOnes() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:935
unsigned EliminateOnes() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:1197
std::shared_ptr< Node > Differentiate(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:1211
mpfr_complex FreshEval_mp(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:1244
int Degree(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:1219
dbl FreshEval_d(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:1232
void print(std::ostream &target) const override
Definition arithmetic.cpp:1202
unsigned EliminateZeros() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:1193
Represents summation and difference Operator.
Definition arithmetic.hpp:80
mpfr_complex FreshEval_mp(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:402
std::shared_ptr< Node > Differentiate(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:190
bool IsHomogeneous(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:317
std::vector< int > MultiDegree(VariableGroup const &vars) const override
Definition arithmetic.cpp:249
void AddOperand(std::shared_ptr< Node > child, bool sign)
Definition arithmetic.hpp:148
unsigned ReduceDepth() override
A mutating function which finds ways to reduce the depth of the tree.
Definition arithmetic.cpp:157
void AddOperand(std::shared_ptr< Node > child) override
Definition arithmetic.hpp:138
void Homogenize(VariableGroup const &vars, std::shared_ptr< Variable > const &homvar) override
Definition arithmetic.cpp:264
unsigned EliminateOnes() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:88
int Degree(std::shared_ptr< Variable > const &v=nullptr) const override
Definition arithmetic.cpp:217
unsigned EliminateZeros() override
A transform function, which eliminates nodes from the tree.
Definition arithmetic.cpp:42
void print(std::ostream &target) const override
Definition arithmetic.cpp:167
dbl FreshEval_d(std::shared_ptr< Variable > const &diff_variable) const override
Definition arithmetic.cpp:374
Interface for all unary Operator types.
Definition operator.hpp:84
Provides the differential Node class.
Forward declarations for types in the node:: namespace.
Defines the abstract Node base class.
Provides the Number Node types, including Rational, Float, and Integer.
Provides the abstract Operator Node type.
Provides the special numbers , , 1, 2, 0, as Nodes.
Provides the Variable Node class.