CppADCodeGen  2.3.0
A C++ Algorithmic Differentiation Package with Source Code Generation
language_dot_arrays.hpp
1 #ifndef CPPAD_CG_LANGUAGE_DOT_ARRAYS_INCLUDED
2 #define CPPAD_CG_LANGUAGE_DOT_ARRAYS_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2016 Ciengis
6  *
7  * CppADCodeGen is distributed under multiple licenses:
8  *
9  * - Eclipse Public License Version 1.0 (EPL1), and
10  * - GNU General Public License Version 3 (GPL3).
11  *
12  * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
13  * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
14  * ----------------------------------------------------------------------------
15  * Author: Joao Leal
16  */
17 
18 namespace CppAD {
19 namespace cg {
20 
21 template<class Base>
22 std::string LanguageDot<Base>::printArrayCreationOp(OperationNode<Base>& array) {
23  CPPADCG_ASSERT_KNOWN(array.getArguments().size() > 0, "Invalid number of arguments for array creation operation");
24  const std::vector<Argument<Base> >& args = array.getArguments();
25  const size_t argSize = args.size();
26 
27  _ss.str("");
28  _ss << "array[" << args.size() << "]";
29  std::string name = printNodeDeclaration(array, _ss);
30 
31  for (size_t i = 0; i < argSize; i++) {
32  // try to use a loop for element assignment
33  size_t newI = printArrayCreationUsingLoop(name, array, i, nullptr);
34 
35  // print elements not assign in a loop
36  if (newI == i) {
37  // individual element assignment
38  std::string aName = print(args[i]);
39 
40  printEdge(aName, name, std::to_string(i)); // std::to_string(i)
41  _code << _endline;
42 
43  } else {
44  i = newI - 1;
45  }
46  }
47 
48  return name;
49 }
50 
51 template<class Base>
52 std::string LanguageDot<Base>::printSparseArrayCreationOp(OperationNode<Base>& array) {
53 
54  const std::vector<size_t>& info = array.getInfo();
55  CPPADCG_ASSERT_KNOWN(info.size() > 0, "Invalid number of information elements for sparse array creation operation");
56 
57  const std::vector<Argument<Base> >& args = array.getArguments();
58  const size_t argSize = args.size();
59 
60  CPPADCG_ASSERT_KNOWN(info.size() == argSize + 1, "Invalid number of arguments for sparse array creation operation");
61 
62  _ss.str("");
63  _ss << "sparse[" << info[0] << "]"; // nnz: args.size()
64  std::string name = printNodeDeclaration(array, _ss);
65 
66  if (argSize == 0)
67  return name; // empty array
68 
69  for (size_t i = 0; i < argSize; i++) {
70  // try to use a loop for element assignment
71  size_t newI = printArrayCreationUsingLoop(name, array, i, &info[i]);
72 
73  // print element values not assign in a loop
74  if (newI == i) {
75  // individual element assignment
76  std::string aName = print(args[i]);
77 
78  printEdge(aName, name, std::to_string(info[i + 1])); // std::to_string(i)
79  _code << _endline;
80 
81  } else {
82  i = newI - 1;
83  }
84  }
85 
86  return name;
87 }
88 
89 template<class Base>
90 inline size_t LanguageDot<Base>::printArrayCreationUsingLoop(const std::string arrayName,
91  const OperationNode<Base>& array,
92  size_t starti,
93  const size_t* indexes) {
94 
95  const std::vector<Argument<Base> >& args = array.getArguments();
96  const size_t argSize = args.size();
97  size_t i = starti + 1;
98 
102  if(args[starti].getParameter() == nullptr)
103  return starti;
104 
105  const Base& value = *args[starti].getParameter();
106  for (; i < argSize; i++) {
107  if (args[i].getParameter() == nullptr ||
108  *args[i].getParameter() != value) {
109  break; // not the same constant value
110  }
111 
112  if (indexes != nullptr && i - starti != indexes[i] - indexes[starti])
113  break; // not the same constant value
114  }
115 
116  if (i - starti < 3)
117  return starti;
118 
119  std::string aName = print(args[starti]);
120 
124  if (indexes != nullptr)
125  printEdge(aName, arrayName, std::to_string(indexes[starti]) + "..." + std::to_string(indexes[i]));
126  else
127  printEdge(aName, arrayName, std::to_string(starti) + "..." + std::to_string(i));
128  _code << _endline;
129 
130  return i;
131 }
132 
133 template<class Base>
135  CPPADCG_ASSERT_KNOWN(op.getArguments().size() == 2, "Invalid number of arguments for array element operation");
136  CPPADCG_ASSERT_KNOWN(op.getArguments()[0].getOperation() != nullptr, "Invalid argument for array element operation");
137  CPPADCG_ASSERT_KNOWN(op.getInfo().size() == 1, "Invalid number of information indexes for array element operation");
138 
139  std::string name = makeNodeName(op);
140 
141  _ss.str("");
142  _ss << "[" << op.getInfo()[0] << "]";
143  printEdges(name, op, std::vector<std::string>{}, std::vector<std::string>{_ss.str()});
144 
145  return name;
146 }
147 
148 } // END cg namespace
149 } // END CppAD namespace
150 
151 #endif
const std::vector< Argument< Base > > & getArguments() const
size_t printArrayCreationUsingLoop(const std::string arrayName, const OperationNode< Base > &array, size_t startj, const size_t *indexes)
const std::vector< size_t > & getInfo() const