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