1#ifndef CPPAD_CG_UTIL_INCLUDED
2#define CPPAD_CG_UTIL_INCLUDED
22template<
class VectorBool,
class Base>
26 size_t m =
fun.Range();
27 CPPADCG_ASSERT_KNOWN(
vx.size() >=
fun.Domain(),
"Invalid vx size")
28 CPPADCG_ASSERT_KNOWN(
vy.size() >= m, "
Invalid vy size")
30 using VectorSet = std::vector<std::set<
size_t> >;
34 for (
size_t i = 0;
i < m;
i++) {
44template<
class VectorSet>
45inline bool isIdentityPattern(
const VectorSet& pattern,
47 CPPADCG_ASSERT_UNKNOWN(pattern.size() >=
mRows)
50 if (pattern[
i].size() != 1 || *pattern[
i].begin() !=
i) {
57template<
class VectorSet>
58inline VectorSet transposePattern(
const VectorSet& pattern,
61 CPPADCG_ASSERT_UNKNOWN(pattern.size() >=
mRows)
65 for (
size_t it : pattern[
i]) {
81template<
class VectorSet,
class VectorSet2>
82inline void addTransMatrixSparsity(
const VectorSet&
a,
85 CPPADCG_ASSERT_UNKNOWN(
a.size() >=
mRows)
88 for (
size_t j :
a[
i]) {
102template<
class VectorSet,
class VectorSet2>
103inline void addTransMatrixSparsity(
const VectorSet&
a,
116template<
class VectorSet,
class VectorSet2>
117inline void addMatrixSparsity(
const VectorSet&
a,
121 CPPADCG_ASSERT_UNKNOWN(
a.size() <=
mRows)
123 for (
size_t i = 0;
i <
mRows;
i++) {
139template<
class VectorSet,
class VectorSet2>
140inline void addMatrixSparsity(
const VectorSet&
a,
142 CPPADCG_ASSERT_UNKNOWN(
result.size() ==
a.size())
161 multMatrixMatrixSparsity(
a,
b,
result,
a.size(),
b.size(),
q);
177template<
class VectorSet,
class VectorSet2>
178inline void multMatrixMatrixSparsity(
const VectorSet&
a,
184 CPPADCG_ASSERT_UNKNOWN(
a.size() >= m)
185 CPPADCG_ASSERT_UNKNOWN(
b.size() >=
n)
186 CPPADCG_ASSERT_UNKNOWN(
result.size() >= m)
190 if (isIdentityPattern(
b,
n)) {
191 addMatrixSparsity(
a, m,
result);
198 for (
size_t jj = 0;
jj <
q;
jj++) {
199 const std::set<size_t>&
colB =
bt[
jj];
201 for (
size_t i = 0;
i < m;
i++) {
202 const std::set<size_t>&
rowA =
a[
i];
227template<
class VectorSet,
class VectorSet2>
228inline void multMatrixTransMatrixSparsity(
const VectorSet&
a,
234 CPPADCG_ASSERT_UNKNOWN(
a.size() >= m)
235 CPPADCG_ASSERT_UNKNOWN(
b.size() >= m)
236 CPPADCG_ASSERT_UNKNOWN(
result.size() >=
n)
240 for (
size_t i = 0;
i < m;
i++) {
241 if (
b[
i].size() > 0) {
251 if (m ==
n && isIdentityPattern(
a, m)) {
257 if (m ==
q && isIdentityPattern(
b, m)) {
258 addTransMatrixSparsity(
a, m,
result);
262 VectorSet at = transposePattern(
a, m,
n);
265 for (
size_t jj = 0;
jj <
q;
jj++) {
266 const std::set<size_t>&
colB =
bt[
jj];
268 for (
size_t i = 0;
i <
n;
i++) {
269 const std::set<size_t>&
rowAt = at[
i];
270 if (!
rowAt.empty()) {
296template<
class VectorSet,
class VectorSet2>
297inline void multMatrixMatrixSparsityTrans(
const VectorSet&
aT,
303 CPPADCG_ASSERT_UNKNOWN(
aT.size() >= m)
304 CPPADCG_ASSERT_UNKNOWN(
b.size() >= m)
308 for (
size_t i = 0;
i < m;
i++) {
309 if (
b[
i].size() > 0) {
319 if (m ==
q && isIdentityPattern(
aT, m)) {
320 addTransMatrixSparsity(
b, m,
rT);
324 VectorSet
a = transposePattern(
aT, m,
q);
327 for (
size_t jj = 0;
jj <
n;
jj++) {
328 for (
size_t i = 0;
i <
q;
i++) {
329 for (
size_t it :
a[
i]) {
339template<
class VectorBool>
340void printSparsityPattern(
const VectorBool& sparsity,
341 const std::string& name,
342 size_t m,
size_t n) {
343 size_t width = std::ceil(std::log10((m >
n) ? m :
n));
345 std::cout << name <<
" sparsity:\n";
347 for (
size_t i = 0;
i < m;
i++) {
348 std::cout <<
" " << std::setw(
width) <<
i <<
": ";
349 for (
size_t j = 0;
j <
n;
j++) {
350 if (sparsity[
i *
n +
j]) {
351 std::cout << std::setw(
width) <<
j <<
" ";
353 std::cout << std::setw(
width) <<
" " <<
" ";
358 std::cout << std::endl;
361template<
class VectorSet>
362void printSparsityPattern(
const VectorSet& sparsity,
363 const std::string& name,
365 size_t maxDim = sparsity.size();
367 for (
size_t i = 0;
i < sparsity.size();
i++) {
368 if (sparsity[
i].size() > 0 && *sparsity[
i].rbegin() >
maxDim) {
369 maxDim = *sparsity[
i].rbegin();
371 nnz += sparsity[
i].size();
378 width2 = std::ceil(std::log10(nnz));
382 std::cout << name <<
" sparsity:\n";
386 for (
size_t i = 0;
i < sparsity.size();
i++) {
387 std::cout <<
" " << std::setw(
width) <<
i <<
": ";
389 for (
size_t j : sparsity[
i]) {
390 if (
j != 0 &&
long(
j) !=
last + 1) {
391 std::cout << std::setw((
j -
last - 1) * (
width3 + 1)) <<
" ";
394 std::cout << std::setw(
width2) <<
e <<
":";
395 std::cout << std::setw(
width) <<
j <<
" ";
401 std::cout << std::endl;
404template<
class VectorSize>
405void printSparsityPattern(
const VectorSize& row,
407 const std::string& name,
409 std::vector<std::set<size_t> > sparsity(m);
410 generateSparsitySet(row, col, sparsity);
411 printSparsityPattern(sparsity, name);
414inline bool intersects(
const std::set<size_t>&
a,
415 const std::set<size_t>&
b) {
416 if (
a.empty() ||
b.empty()) {
418 }
else if (*
a.rbegin() < *
b.begin() ||
419 *
a.begin() > *
b.rbegin()) {
423 if (
a.size() <
b.size()) {
424 for (
size_t ita :
a) {
425 if (
b.find(
ita) !=
b.end()) {
430 for (
size_t itb :
b) {
431 if (
a.find(
itb) !=
a.end()) {
440template<
class VectorSizet,
class VectorSet>
442 size_t m,
size_t n) {
451 pattern.resize(m,
n, nnz);
456 pattern.set(
e++,
i,
j);
470inline CodeHandler<Base>* findHandler(
const std::vector<CG<Base> >&
ty) {
471 for (
size_t i = 0;
i <
ty.size();
i++) {
472 if (
ty[
i].getCodeHandler() !=
nullptr) {
473 return ty[
i].getCodeHandler();
480inline CodeHandler<Base>* findHandler(
const CppAD::vector<CG<Base> >&
ty) {
481 for (
size_t i = 0;
i <
ty.size();
i++) {
482 if (
ty[
i].getCodeHandler() !=
nullptr) {
483 return ty[
i].getCodeHandler();
491 for (
size_t i = 0;
i <
ty.size();
i++) {
492 if (
ty[
i].getCodeHandler() !=
nullptr) {
493 return ty[
i].getCodeHandler();
501 if (
tx.isParameter()) {
509inline std::vector<Argument<Base> > asArguments(
const std::vector<CG<Base> >&
tx) {
510 std::vector<Argument<Base> > arguments(
tx.size());
511 for (
size_t i = 0;
i < arguments.size();
i++) {
512 arguments[
i] = asArgument(
tx[
i]);
518inline std::vector<Argument<Base> > asArguments(
const CppAD::vector<CG<Base> >&
tx) {
519 std::vector<Argument<Base> > arguments(
tx.size());
520 for (
size_t i = 0;
i < arguments.size();
i++) {
521 arguments[
i] = asArgument(
tx[
i]);
536template<
class Key,
class Value>
537void mapKeys(
const std::map<Key, Value>& map, std::set<Key>& keys) {
538 for (
const auto&
p : map) {
539 keys.insert(keys.end(),
p.first);
549template<
class Key,
class Value>
550void mapKeys(
const std::map<Key, Value>& map, std::vector<Key>& keys) {
551 keys.resize(map.size());
554 typename std::map<Key, Value>::const_iterator
it;
555 for (
it = map.begin();
it != map.end(); ++
it,
i++) {
567template<
class Key,
class Value>
568bool compareMapKeys(
const std::map<Key, Value>& map,
const std::set<Key>& keys) {
569 if (map.size() != keys.size())
572 typename std::map<Key, Value>::const_iterator
itm = map.begin();
573 typename std::set<Key>::const_iterator
itk = keys.begin();
589template<
class Key,
class Value>
590inline std::map<Key, Value> filterBykeys(
const std::map<Key, Value>& m,
591 const std::set<Key>& keys) {
594 typename std::map<Key, Value>::const_iterator
itM;
596 for (
const Key&
k : keys) {
598 if (
itM != m.end()) {
615inline int compare(
const std::set<T>&
s1,
const std::set<T>&
s2) {
616 if (
s1.size() <
s2.size()) {
618 }
else if (
s1.size() >
s2.size()) {
621 typename std::set<T>::const_iterator
it1,
it2;
636 bool operator() (
const std::set<T>&
lhs,
const std::set<T>&
rhs)
const {
637 return compare(
lhs,
rhs) == -1;
645inline void print(
const Base& v) {
649template<
class Key,
class Value>
650inline void print(
const std::map<Key, Value>& m) {
651 for (
const std::pair<Key, Value>&
p : m) {
652 std::cout <<
p.first <<
" : ";
654 std::cout << std::endl;
659inline void print(
const std::set<Base>& s) {
662 for (
auto itj = s.begin();
itj != s.end(); ++
itj) {
663 if (
itj != s.begin()) std::cout <<
" ";
671inline void print(
const std::set<Base*>& s) {
674 for (
const auto itj = s.begin();
itj != s.end(); ++
itj) {
675 if (
itj != s.begin()) std::cout <<
" ";
677 if (v ==
nullptr) std::cout <<
"NULL";
685inline void print(
const std::vector<Base>& v) {
688 for (
size_t i = 0;
i < v.size();
i++) {
689 if (
i != 0) std::cout <<
" ";
696template<
class VectorSize,
class VectorBase>
697inline void printTripletMatrix(
const VectorSize &rows,
700 size_t n = values.size();
704 for (
size_t i = 0;
i <
n; ++
i) {
705 std::cout <<
"[ " << rows[
i] <<
", " << cols[
i] <<
"] -> " << values[
i] << std::endl;
724inline CG<Base> makePrintValue(
const std::string&
before,
726 const std::string&
after =
"") {
729 if (x.getOperationNode() !=
nullptr) {
730 auto*
handler = x.getCodeHandler();
732 if (x.isValueDefined())
733 out.setValue(x.getValue());
751inline void replaceString(std::string&
text,
761inline std::vector<std::string> explode(
const std::string&
text,
763 std::vector<std::string>
matches;
773 if (
pos == std::string::npos) {
787inline std::string implode(
const std::vector<std::string>&
text,
791 }
else if (
text.size() == 1) {
796 for (
const auto& s:
text)
800 for (
size_t i = 1;
i <
text.size(); ++
i) {
808inline std::string readStringFromFile(
const std::string&
path) {
bool GreaterThanZero(const cg::CG< Base > &x)