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