dd113a523078a34f86ff4d603c47ca0759ff35e0
[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         return NULL;
74     }
75
76     colIndexes[0] = 0;
77
78     for (int K = 0; K < pSparse->getRows(); ++K)
79     {
80         colIndexes[K + 1] = colIndexes[K] + itemsRow[K];
81     }
82
83     int* rowIndexes = (int*)MALLOC(sizeof(int) *  nonZeros);
84     if (rowIndexes == NULL)
85     {
86         FREE(sparseData);
87         FREE(colIndexes);
88         Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
89         return NULL;
90     }
91
92     pSparse->getColPos(colPos);
93     for (int K = 0; K < nonZeros; ++K)
94     {
95         rowIndexes[K] = colPos[K] - 1;
96     }
97
98
99     /* Create Matlab Sparse matrix data */
100     sparseData->nzmax = nonZeros;
101     sparseData->nir = nonZeros;
102     sparseData->ir = rowIndexes;
103     /* sparseData->njc   = scilabSparse.nel + 1; */
104     sparseData->njc = pSparse->getRows() + 1;
105     sparseData->jc = colIndexes;
106     sparseData->ndata = nonZeros;
107     /* get position data*/
108     int* iPositVal = new int[nonZeros];
109
110     int idx = 0;
111     for (int i = 0; i < pSparse->getRows(); i++)
112     {
113         for (int j = 0; j < itemsRow[i]; j++)
114         {
115             iPositVal[idx] = (colPos[idx] - 1) * pSparse->getRows() + i;
116             ++idx;
117         }
118     }
119
120     psize_t = (size_t*)MALLOC(Dims * sizeof(size_t));
121     if (rowIndexes == NULL)
122     {
123         FREE(sparseData);
124         FREE(rowIndexes);
125         FREE(colIndexes);
126         Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
127         return NULL;
128     }
129
130     psize_t[0] = (int)pDims[1];
131     psize_t[1] = (int)pDims[0];
132
133
134
135     if (pSparse->isComplex())
136     {
137         struct mat_complex_split_t* data;
138         double* dataReal = NULL;
139         double* dataImg = NULL;
140         if ((dataReal = (double*)MALLOC(sizeof(double) * nonZeros)) == NULL)
141         {
142             FREE(psize_t);
143             FREE(sparseData);
144             FREE(colIndexes);
145             FREE(rowIndexes);
146             Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
147             return NULL;
148         }
149
150         if ((dataImg = (double*)MALLOC(sizeof(double) * nonZeros)) == NULL)
151         {
152             FREE(dataReal);
153             FREE(psize_t);
154             FREE(sparseData);
155             FREE(colIndexes);
156             FREE(rowIndexes);
157             Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
158             return NULL;
159         }
160
161         if ((data = (mat_complex_split_t*)MALLOC(sizeof(mat_complex_split_t))) == NULL)
162         {
163             FREE(dataImg);
164             FREE(dataReal);
165             FREE(psize_t);
166             FREE(sparseData);
167             FREE(colIndexes);
168             FREE(rowIndexes);
169             Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
170             return NULL;
171         }
172
173         std::complex<double> complexData;
174         for (int K = 0; K < nonZeros; ++K)
175         {
176             complexData = pSparse->getImg(iPositVal[K]);
177             dataReal[K] = complexData.real();
178             dataImg[K] = (-1 * complexData.imag());
179
180         }
181         data->Re = dataReal;
182         data->Im = dataImg;
183
184         sparseData->data = (void*)data;
185
186         pMatVarOut = Mat_VarCreate(name, MAT_C_SPARSE, MAT_T_DOUBLE, Dims, psize_t, sparseData, MAT_F_COMPLEX | MAT_F_DONT_COPY_DATA);
187     }
188     else
189     {
190         double* data = NULL;
191
192         if ((data = (double*)MALLOC(sizeof(double) * nonZeros)) == NULL)
193         {
194             FREE(psize_t);
195             FREE(sparseData);
196             FREE(colIndexes);
197             FREE(rowIndexes);
198             Scierror(999, _("%s: No more memory.\n"), "GetSparseMatVar");
199             return NULL;
200         }
201
202         for (int K = 0; K < nonZeros; ++K)
203         {
204             data[K] = pSparse->getReal(iPositVal[K]);
205         }
206
207
208         sparseData->data = (void*)data;
209
210         pMatVarOut = Mat_VarCreate(name, MAT_C_SPARSE, MAT_T_DOUBLE, Dims, psize_t, sparseData, 0 | MAT_F_DONT_COPY_DATA);
211     }
212
213     FREE(psize_t);
214     return pMatVarOut;
215 }