a867d5b0ffcc562ba74b8ae8098f39cb8a8b4871
[scilab.git] / scilab / modules / matio / src / cpp / GetSparseVariable.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2008 - INRIA - Vincent COUVERT
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 #include "GetMatlabVariable.hxx"
17
18 extern "C"
19 {
20 #include "api_scilab.h"
21 #include "scisparse.h"
22 }
23
24 matvar_t *GetSparseVariable(void *pvApiCtx, int iVar, const char *name, int * parent, int item_position)
25 {
26
27     types::GatewayStruct* pGS = (types::GatewayStruct*)pvApiCtx;
28     types::typed_list in = *pGS->m_pIn;
29
30     if (in[iVar - 1]->isSparse() == false)
31     {
32         Scierror(999, _("%s: Wrong type for first input argument: Sparse matrix expected.\n"), "GetSparseVariable");
33         return NULL;
34     }
35
36     types::Sparse* pSparse = in[iVar - 1]->getAs<types::Sparse>();
37
38     return GetSparseMatVar(pSparse, name);
39 }
40
41 matvar_t* GetSparseMatVar(types::Sparse* pSparse, const char *name)
42 {
43     int Dims = pSparse->getDims();
44     int* pDims = pSparse->getDimsArray();
45     int isize = pSparse->getSize();
46     size_t* psize_t = NULL;
47     matvar_t * pMatVarOut = NULL;
48
49     if (pSparse->getDims() > 2)
50     {
51         Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
52         return NULL;
53     }
54
55     mat_sparse_t *sparseData = NULL;
56     sparseData = (mat_sparse_t*)MALLOC(sizeof(mat_sparse_t));
57     if (sparseData == NULL)
58     {
59         Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
60         return NULL;
61     }
62
63     int nonZeros = pSparse->nonZeros();
64     int* colPos = new int[nonZeros];
65     int* itemsRow = new int[pSparse->getRows()];
66     pSparse->getNbItemByRow(itemsRow);
67
68     int* colIndexes = (int*)MALLOC(sizeof(int) *  (pSparse->getRows() + 1));
69     if (colIndexes == NULL)
70     {
71         FREE(sparseData);
72         Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
73         delete[] colPos;
74         delete[] itemsRow;
75         return NULL;
76     }
77
78     colIndexes[0] = 0;
79
80     for (int K = 0; K < pSparse->getRows(); ++K)
81     {
82         colIndexes[K + 1] = colIndexes[K] + itemsRow[K];
83     }
84
85     int* rowIndexes = (int*)MALLOC(sizeof(int) *  nonZeros);
86     if (rowIndexes == NULL)
87     {
88         FREE(sparseData);
89         FREE(colIndexes);
90         delete[] colPos;
91         delete[] itemsRow;
92         Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
93         return NULL;
94     }
95
96     pSparse->getColPos(colPos);
97     for (int K = 0; K < nonZeros; ++K)
98     {
99         rowIndexes[K] = colPos[K] - 1;
100     }
101
102
103     /* Create Matlab Sparse matrix data */
104     sparseData->nzmax = nonZeros;
105     sparseData->nir = nonZeros;
106     sparseData->ir = rowIndexes;
107     /* sparseData->njc   = scilabSparse.nel + 1; */
108     sparseData->njc = pSparse->getRows() + 1;
109     sparseData->jc = colIndexes;
110     sparseData->ndata = nonZeros;
111     /* get position data*/
112     int* iPositVal = new int[nonZeros];
113
114     int idx = 0;
115     for (int i = 0; i < pSparse->getRows(); i++)
116     {
117         for (int j = 0; j < itemsRow[i]; j++)
118         {
119             iPositVal[idx] = (colPos[idx] - 1) * pSparse->getRows() + i;
120             ++idx;
121         }
122     }
123
124     psize_t = (size_t*)MALLOC(Dims * sizeof(size_t));
125     if (psize_t == NULL)
126     {
127         FREE(sparseData);
128         FREE(rowIndexes);
129         FREE(colIndexes);
130         delete[] itemsRow;
131         delete[] colPos;
132         delete[] iPositVal;
133         Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
134         return NULL;
135     }
136     psize_t[0] = (int)pDims[1];
137     psize_t[1] = (int)pDims[0];
138
139     if (pSparse->isComplex())
140     {
141         struct mat_complex_split_t* data;
142         double* dataReal = NULL;
143         double* dataImg = NULL;
144         if ((dataReal = (double*)MALLOC(sizeof(double) * nonZeros)) == NULL)
145         {
146             FREE(psize_t);
147             FREE(sparseData);
148             FREE(colIndexes);
149             FREE(rowIndexes);
150             delete[] itemsRow;
151             delete[] colPos;
152             delete[] iPositVal;
153             Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
154             return NULL;
155         }
156
157         if ((dataImg = (double*)MALLOC(sizeof(double) * nonZeros)) == NULL)
158         {
159             FREE(dataReal);
160             FREE(psize_t);
161             FREE(sparseData);
162             FREE(colIndexes);
163             FREE(rowIndexes);
164             delete[] itemsRow;
165             delete[] colPos;
166             delete[] iPositVal;
167             Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
168             return NULL;
169         }
170
171         if ((data = (mat_complex_split_t*)MALLOC(sizeof(mat_complex_split_t))) == NULL)
172         {
173             FREE(dataImg);
174             FREE(dataReal);
175             FREE(psize_t);
176             FREE(sparseData);
177             FREE(colIndexes);
178             FREE(rowIndexes);
179             delete[] itemsRow;
180             delete[] colPos;
181             delete[] iPositVal;
182             Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
183             return NULL;
184         }
185
186         std::complex<double> complexData;
187         for (int K = 0; K < nonZeros; ++K)
188         {
189             complexData = pSparse->getImg(iPositVal[K]);
190             dataReal[K] = complexData.real();
191             dataImg[K] = (-1 * complexData.imag());
192
193         }
194         data->Re = dataReal;
195         data->Im = dataImg;
196
197         sparseData->data = (void*)data;
198
199         pMatVarOut = Mat_VarCreate(name, MAT_C_SPARSE, MAT_T_DOUBLE, Dims, psize_t, sparseData, MAT_F_COMPLEX | MAT_F_DONT_COPY_DATA);
200     }
201     else
202     {
203         double* data = NULL;
204
205         if ((data = (double*)MALLOC(sizeof(double) * nonZeros)) == NULL)
206         {
207             FREE(psize_t);
208             FREE(sparseData);
209             FREE(colIndexes);
210             FREE(rowIndexes);
211             delete[] itemsRow;
212             delete[] colPos;
213             delete[] iPositVal;
214             Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
215             return NULL;
216         }
217
218         for (int K = 0; K < nonZeros; ++K)
219         {
220             data[K] = pSparse->getReal(iPositVal[K]);
221         }
222
223
224         sparseData->data = (void*)data;
225
226         pMatVarOut = Mat_VarCreate(name, MAT_C_SPARSE, MAT_T_DOUBLE, Dims, psize_t, sparseData, 0 | MAT_F_DONT_COPY_DATA);
227     }
228
229     FREE(psize_t);
230     delete[] iPositVal;
231     delete[] colPos;
232     delete[] itemsRow;
233     return pMatVarOut;
234 }