Loading...
Searching...
No Matches
is_lower.cpp
1#include <symengine/basic.h>
2#include <symengine/assumptions.h>
3#include <symengine/visitor.h>
4#include <symengine/test_visitors.h>
5
6namespace SymEngine
7{
8
9class MatrixLowerVisitor : public BaseVisitor<MatrixLowerVisitor>
10{
11private:
12 tribool is_lower_;
13 const Assumptions *assumptions_;
14
15public:
16 MatrixLowerVisitor(const Assumptions *assumptions)
17 : assumptions_(assumptions)
18 {
19 }
20
21 void bvisit(const Basic &x){};
22 void bvisit(const MatrixExpr &x)
23 {
24 is_lower_ = tribool::indeterminate;
25 }
26
27 void bvisit(const IdentityMatrix &x)
28 {
29 is_lower_ = tribool::tritrue;
30 }
31
32 void bvisit(const ZeroMatrix &x)
33 {
34 is_lower_ = is_square(x, assumptions_);
35 }
36
37 void bvisit(const DiagonalMatrix &x)
38 {
39 is_lower_ = tribool::tritrue;
40 }
41
42 void bvisit(const ImmutableDenseMatrix &x)
43 {
44 size_t nrows = x.nrows();
45 size_t ncols = x.ncols();
46 if (nrows != ncols) {
47 is_lower_ = tribool::trifalse;
48 return;
49 }
50 ZeroVisitor visitor(assumptions_);
51 is_lower_ = tribool::tritrue;
52 for (size_t i = 0; i < nrows; i++) {
53 for (size_t j = i + 1; j < nrows; j++) {
54 is_lower_ = and_tribool(is_lower_, visitor.apply(*x.get(i, j)));
55 if (is_false(is_lower_)) {
56 return;
57 }
58 }
59 }
60 }
61
62 void bvisit(const MatrixAdd &x)
63 {
64 bool found_nonlower = false;
65 for (auto &elt : x.get_terms()) {
66 elt->accept(*this);
67 if (is_indeterminate(is_lower_)) {
68 return;
69 } else if (is_false(is_lower_)) {
70 if (found_nonlower) {
71 return;
72 } else {
73 found_nonlower = true;
74 }
75 }
76 }
77 if (found_nonlower) {
78 is_lower_ = tribool::trifalse;
79 } else {
80 is_lower_ = tribool::tritrue;
81 }
82 }
83
84 void bvisit(const HadamardProduct &x)
85 {
86 // lower x (lower | nolower | indeterminate) x ... = lower
87 // (indet | nolower) x (indet | nocwlower) x ... = indeterminate
88 for (auto &elt : x.get_factors()) {
89 elt->accept(*this);
90 if (is_true(is_lower_)) {
91 return;
92 }
93 }
94 is_lower_ = tribool::indeterminate;
95 }
96
97 tribool apply(const MatrixExpr &s)
98 {
99 s.accept(*this);
100 return is_lower_;
101 }
102};
103
104tribool is_lower(const MatrixExpr &m, const Assumptions *assumptions)
105{
106 MatrixLowerVisitor visitor(assumptions);
107 return visitor.apply(m);
108}
109
110} // namespace SymEngine
The base class for SymEngine.
The lowest unit of symbolic representation.
Definition: basic.h:97
Main namespace for SymEngine package.
Definition: add.cpp:19