1 //   Copyright 2017 Steven Diamond
2 //
3 //   Licensed under the Apache License, Version 2.0 (the "License");
4 //   you may not use this file except in compliance with the License.
5 //   You may obtain a copy of the License at
6 //
7 //       http://www.apache.org/licenses/LICENSE-2.0
8 //
9 //   Unless required by applicable law or agreed to in writing, software
10 //   distributed under the License is distributed on an "AS IS" BASIS,
11 //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 //   See the License for the specific language governing permissions and
13 //   limitations under the License.
14 
15 #ifndef PROBLEMDATA_H
16 #define PROBLEMDATA_H
17 
18 #include <map>
19 #include <vector>
20 
21 /* Stores the result of calling BUILD_MATRIX on a collection of LinOp
22  * trees. */
23 class ProblemData {
24 public:
25   /* COO sparse matrix representation. V stores the data, I the row indices
26    * and J the column indices. */
operator ()hash27   std::map<int, std::vector<std::vector<double> > > TensorV;
28   std::map<int, std::vector<std::vector<int> > > TensorI;
29   std::map<int, std::vector<std::vector<int> > > TensorJ;
30 
31   // Pointers needed to extract V, I, J.
32   int param_id;
operator ()equal_to33   int vec_idx;
34 
35   // Initialize TensorV/I/J for the given parameter.
36   void init_id(int new_param_id, int param_size) {
37     assert(TensorV.count(new_param_id) == 0);
38     std::vector<std::vector<double> > vecV(param_size);
swap(hash_t &,hash_t &)39     std::vector<std::vector<int> > vecI(param_size);
40     std::vector<std::vector<int> > vecJ(param_size);
swap(equal_to_t &,equal_to_t &)41     for (int i = 0; i < param_size; ++i) {
42       std::vector<double> elemV;
43       std::vector<int> elemI;
44       std::vector<int> elemJ;
test01()45       vecV.push_back(elemV);
46       vecI.push_back(elemI);
47       vecJ.push_back(elemJ);
48     }
49     TensorV[new_param_id] = vecV;
50     TensorI[new_param_id] = vecI;
51     TensorJ[new_param_id] = vecJ;
52   }
53 
54   /*******************************************
55    * The functions below return problemData vectors as contiguous 1d
test02()56    * numpy arrays.
57    *
58    * Note the function prototypes must match CVXCanon.i exactly to
59    * properly run and compile.
60    *
61    * Each function is wrapped using SWIG's numpy.i typemap, so can
62    * be called in python using
63    *
64    * 				problemData.getV(N)
65    *
66    * where N is the length of the vector V. The double *pointer VALUES
67    * is generated by the wrapper, which allocates space for NUM_VALUES
68    * elements. Thus, NUM_VALUES must be exactly the length of the array.
69    ********************************************/
70 
71   // Get length of V, I, J.
72   int getLen() {
73     std::vector<double> V = TensorV[param_id][vec_idx];
74     return V.size();
75   }
test04()76 
77   /**
78    * Returns the data vector V as a contiguous 1D numpy array.
79    */
80   void getV(double *values, int num_values) {
81     std::vector<double> V = TensorV[param_id][vec_idx];
82     for (int i = 0; i < num_values; i++) {
83       values[i] = V[i];
84     }
85   }
test05()86 
87   /**
88    * Returns the row index vector I as a contiguous 1D numpy array.
89    */
90   void getI(double *values, int num_values) {
91     std::vector<int> I = TensorI[param_id][vec_idx];
92     for (int i = 0; i < num_values; i++) {
93       values[i] = I[i];
94     }
95   }
test06()96 
97   /**
98    * Returns the column index vector J as a contiguous 1D numpy array.
99    */
100   void getJ(double *values, int num_values) {
101     std::vector<int> J = TensorJ[param_id][vec_idx];
102     for (int i = 0; i < num_values; i++) {
103       values[i] = J[i];
104     }
105   }
106 };
107 
108 #endif
109