File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/auto/share/dist/Alien-Kiwisolver/include/kiwi/row.h
Criterion Covered Total %
statement 53 54 98.1
branch 24 34 70.5
condition n/a
subroutine n/a
pod n/a
total 77 88 87.5


line stmt bran cond sub pod time code
1             /*-----------------------------------------------------------------------------
2             | Copyright (c) 2013-2017, Nucleic Development Team.
3             |
4             | Distributed under the terms of the Modified BSD License.
5             |
6             | The full license is in the file LICENSE, distributed with this software.
7             |----------------------------------------------------------------------------*/
8             #pragma once
9             #include "maptype.h"
10             #include "symbol.h"
11             #include "util.h"
12              
13             namespace kiwi
14             {
15              
16             namespace impl
17             {
18              
19             class Row
20             {
21              
22             public:
23             using CellMap = MapType<Symbol, double>;
24              
25 10           Row() : Row(0.0) {}
26              
27 3221 50         Row(double constant) : m_constant(constant) {}
28              
29 1660           Row(const Row &other) = default;
30              
31 8102           ~Row() = default;
32              
33 15214           const CellMap &cells() const
34             {
35 15214           return m_cells;
36             }
37              
38 1021717           double constant() const
39             {
40 1021717           return m_constant;
41             }
42              
43             /* Add a constant value to the row constant.
44              
45             The new value of the constant is returned.
46              
47             */
48 1832           double add(double value)
49             {
50 1832           return m_constant += value;
51             }
52              
53             /* Insert a symbol into the row with a given coefficient.
54              
55             If the symbol already exists in the row, the coefficient will be
56             added to the existing coefficient. If the resulting coefficient
57             is zero, the symbol will be removed from the row.
58              
59             */
60 16810           void insert(const Symbol &symbol, double coefficient = 1.0)
61             {
62 16810 50         if (nearZero(m_cells[symbol] += coefficient))
63 0           m_cells.erase(symbol);
64 16810           }
65              
66             /* Insert a row into this row with a given coefficient.
67              
68             The constant and the cells of the other row will be multiplied by
69             the coefficient and added to this row. Any cell with a resulting
70             coefficient of zero will be removed from the row.
71              
72             */
73 1225667           void insert(const Row &other, double coefficient = 1.0)
74             {
75 1225667           m_constant += other.m_constant * coefficient;
76              
77 10784308 100         for (const auto & cellPair : other.m_cells)
78             {
79 9558641           double coeff = cellPair.second * coefficient;
80 9558641 50         if (nearZero(m_cells[cellPair.first] += coeff))
    100          
81 3538214 50         m_cells.erase(cellPair.first);
82             }
83 1225667           }
84              
85             /* Remove the given symbol from the row.
86              
87             */
88 172254           void remove(const Symbol &symbol)
89             {
90 172254 50         auto it = m_cells.find(symbol);
91 172254 100         if (it != m_cells.end())
92 24289 50         m_cells.erase(it);
93 172254           }
94              
95             /* Reverse the sign of the constant and all cells in the row.
96              
97             */
98 578           void reverseSign()
99             {
100 578           m_constant = -m_constant;
101 3510 100         for (auto &cellPair : m_cells)
102 2932           cellPair.second = -cellPair.second;
103 578           }
104              
105             /* Solve the row for the given symbol.
106              
107             This method assumes the row is of the form a * x + b * y + c = 0
108             and (assuming solve for x) will modify the row to represent the
109             right hand side of x = -b/a * y - c / a. The target symbol will
110             be removed from the row, and the constant and other cells will
111             be multiplied by the negative inverse of the target coefficient.
112              
113             The given symbol *must* exist in the row.
114              
115             */
116 10753           void solveFor(const Symbol &symbol)
117             {
118 10753           double coeff = -1.0 / m_cells[symbol];
119 10753           m_cells.erase(symbol);
120 10753           m_constant *= coeff;
121 112817 100         for (auto &cellPair : m_cells)
122 102064           cellPair.second *= coeff;
123 10753           }
124              
125             /* Solve the row for the given symbols.
126              
127             This method assumes the row is of the form x = b * y + c and will
128             solve the row such that y = x / b - c / b. The rhs symbol will be
129             removed from the row, the lhs added, and the result divided by the
130             negative inverse of the rhs coefficient.
131              
132             The lhs symbol *must not* exist in the row, and the rhs symbol
133             *must* exist in the row.
134              
135             */
136 7952           void solveFor(const Symbol &lhs, const Symbol &rhs)
137             {
138 7952           insert(lhs, -1.0);
139 7952           solveFor(rhs);
140 7952           }
141              
142             /* Get the coefficient for the given symbol.
143              
144             If the symbol does not exist in the row, zero will be returned.
145              
146             */
147 952848           double coefficientFor(const Symbol &symbol) const
148             {
149 952848 50         CellMap::const_iterator it = m_cells.find(symbol);
150 952848 100         if (it == m_cells.end())
151 587894           return 0.0;
152 952848           return it->second;
153             }
154              
155             /* Substitute a symbol with the data from another row.
156              
157             Given a row of the form a * x + b and a substitution of the
158             form x = 3 * y + c the row will be updated to reflect the
159             expression 3 * a * y + a * c + b.
160              
161             If the symbol does not exist in the row, this is a no-op.
162              
163             */
164 3078111           void substitute(const Symbol &symbol, const Row &row)
165             {
166 3078111 50         auto it = m_cells.find(symbol);
167 3078111 100         if (it != m_cells.end())
168             {
169 1223028           double coefficient = it->second;
170 1223028 50         m_cells.erase(it);
171 1223028 50         insert(row, coefficient);
172             }
173 3078111           }
174              
175             private:
176             CellMap m_cells;
177             double m_constant;
178             };
179              
180             } // namespace impl
181              
182             } // namespace kiwi