* Port to matio 1.5.0 * Code cleaning * Prepare code for Scilab 6 (YaSp branch merge)
[scilab.git] / scilab / modules / matio / src / c / GetSparseVariable.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2008 - INRIA - Vincent COUVERT
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "GetMatlabVariable.h"
14 #include "stack-c.h"
15 #include "api_scilab.h"
16
17 matvar_t *GetSparseVariable(void *pvApiCtx, int iVar, const char *name, int * parent, int item_position)
18 {
19     int K = 0;
20     int rank = 0;
21     size_t* pszDims = NULL;
22     int *dims = NULL;
23     double *data = NULL;
24     matvar_t *createdVar = NULL;
25     mat_sparse_t *sparseData = NULL;
26     SciSparse scilabSparse;
27     int *colIndexes = NULL;
28     int *rowIndexes = NULL;
29     int * var_addr = NULL;
30     int * item_addr = NULL;
31     int var_type;
32     SciErr sciErr;
33
34     if (parent == NULL)
35     {
36         sciErr = getVarAddressFromPosition(pvApiCtx, iVar, &var_addr);
37         if (sciErr.iErr)
38         {
39             printError(&sciErr, 0);
40             return 0;
41         }
42         sciErr = getVarType(pvApiCtx, var_addr, &var_type);
43         if (sciErr.iErr)
44         {
45             printError(&sciErr, 0);
46             return 0;
47         }
48     }
49     else
50     {
51         sciErr = getListItemAddress(pvApiCtx, parent, item_position, &item_addr);
52         if (sciErr.iErr)
53         {
54             printError(&sciErr, 0);
55             return 0;
56         }
57         sciErr = getVarType(pvApiCtx, item_addr, &var_type);
58         if (sciErr.iErr)
59         {
60             printError(&sciErr, 0);
61             return 0;
62         }
63     }
64
65     if (var_type == sci_sparse)
66     {
67         sparseData = (mat_sparse_t*) MALLOC(sizeof(mat_sparse_t));
68         if (sparseData == NULL)
69         {
70             Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
71             return FALSE;
72         }
73
74         rank = 2;
75         if ((dims = (int*) MALLOC (sizeof(int) * rank)) == NULL)
76         {
77             Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
78             return NULL;
79         }
80
81         if (isVarComplex(pvApiCtx, var_addr))
82         {
83             if (parent == NULL)
84             {
85                 getAllocatedComplexSparseMatrix(pvApiCtx, var_addr, &dims[1], &dims[0],
86                                                 &scilabSparse.nel, &scilabSparse.mnel,
87                                                 &scilabSparse.icol, &scilabSparse.R,
88                                                 &scilabSparse.I);
89             }
90             else
91             {
92                 sciErr = getSparseMatrixInList(pvApiCtx, parent, item_position, &dims[1], &dims[0],
93                                                &scilabSparse.nel, NULL, NULL, NULL);
94                 if (sciErr.iErr)
95                 {
96                     printError(&sciErr, 0);
97                     return 0;
98                 }
99                 scilabSparse.mnel = (int *)MALLOC(dims[1] * sizeof(int));
100                 if (scilabSparse.mnel == NULL)
101                 {
102                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
103
104                     FREE(scilabSparse.mnel);
105
106                     return FALSE;
107                 }
108                 scilabSparse.icol = (int *)MALLOC(scilabSparse.nel * sizeof(int));
109                 if (scilabSparse.icol == NULL)
110                 {
111                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
112
113                     FREE(scilabSparse.mnel);
114                     FREE(scilabSparse.icol);
115
116                     return FALSE;
117                 }
118                 scilabSparse.R    = (double *)MALLOC(scilabSparse.nel * sizeof(double));
119                 if (scilabSparse.R == NULL)
120                 {
121                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
122
123                     FREE(scilabSparse.mnel);
124                     FREE(scilabSparse.icol);
125                     FREE(scilabSparse.R);
126
127                     return FALSE;
128                 }
129                 scilabSparse.I    = (double *)MALLOC(scilabSparse.nel * sizeof(double));
130                 if (scilabSparse.I == NULL)
131                 {
132                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
133
134                     FREE(scilabSparse.mnel);
135                     FREE(scilabSparse.icol);
136                     FREE(scilabSparse.R);
137                     FREE(scilabSparse.I);
138
139                     return FALSE;
140                 }
141                 sciErr = getComplexSparseMatrixInList(pvApiCtx, parent, item_position, &dims[1], &dims[0],
142                                                       &scilabSparse.nel, &scilabSparse.mnel,
143                                                       &scilabSparse.icol, &scilabSparse.R, &scilabSparse.I);
144                 if (sciErr.iErr)
145                 {
146                     printError(&sciErr, 0);
147                     return 0;
148                 }
149             }
150
151             scilabSparse.it = 1;
152
153         }
154         else
155         {
156             if (parent == NULL)
157             {
158                 getAllocatedSparseMatrix(pvApiCtx, var_addr, &dims[1], &dims[0],
159                                          &scilabSparse.nel, &scilabSparse.mnel,
160                                          &scilabSparse.icol, &scilabSparse.R);
161             }
162             else
163             {
164                 sciErr = getSparseMatrixInList(pvApiCtx, parent, item_position, &dims[1], &dims[0],
165                                                &scilabSparse.nel, NULL, NULL, NULL);
166                 if (sciErr.iErr)
167                 {
168                     printError(&sciErr, 0);
169                     return 0;
170                 }
171                 scilabSparse.mnel = (int *)MALLOC(dims[1] * sizeof(int));
172                 if (scilabSparse.mnel == NULL)
173                 {
174                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
175
176                     FREE(scilabSparse.mnel);
177
178                     return FALSE;
179                 }
180                 scilabSparse.icol = (int *)MALLOC(scilabSparse.nel * sizeof(int));
181                 if (scilabSparse.icol == NULL)
182                 {
183                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
184
185                     FREE(scilabSparse.mnel);
186                     FREE(scilabSparse.icol);
187
188                     return FALSE;
189                 }
190                 scilabSparse.R    = (double *)MALLOC(scilabSparse.nel * sizeof(double));
191                 if (scilabSparse.R == NULL)
192                 {
193                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
194
195                     FREE(scilabSparse.mnel);
196                     FREE(scilabSparse.icol);
197                     FREE(scilabSparse.R);
198
199                     return FALSE;
200                 }
201                 sciErr = getSparseMatrixInList(pvApiCtx, parent, item_position, &dims[1], &dims[0],
202                                                &scilabSparse.nel, &scilabSparse.mnel,
203                                                &scilabSparse.icol, &scilabSparse.R);
204                 if (sciErr.iErr)
205                 {
206                     printError(&sciErr, 0);
207                     return 0;
208                 }
209             }
210
211             scilabSparse.it = 0;
212         }
213
214         scilabSparse.m = dims[1];
215         scilabSparse.n = dims[0];
216
217         /* colIndexes = (int*) MALLOC(sizeof(int) *  (scilabSparse.nel + 1));  */
218         colIndexes = (int*) MALLOC(sizeof(int) *  (scilabSparse.m + 1));
219         if (colIndexes == NULL)
220         {
221             Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
222
223             if (scilabSparse.it)
224             {
225                 freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
226             }
227             else
228             {
229                 freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
230             }
231
232             return FALSE;
233         }
234
235         colIndexes[0] = 0;
236         /* for (K=0; K<scilabSparse.nel; K++) */
237         for (K = 0; K < scilabSparse.m; K++)
238         {
239             colIndexes[K + 1] = colIndexes[K] + scilabSparse.mnel[K];
240         }
241
242         rowIndexes = (int*) MALLOC(sizeof(int) *  scilabSparse.nel);
243         if (rowIndexes == NULL)
244         {
245             Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
246
247             if (scilabSparse.it)
248             {
249                 freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
250             }
251             else
252             {
253                 freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
254             }
255
256             return FALSE;
257         }
258
259         for (K = 0; K < scilabSparse.nel; K++)
260         {
261             rowIndexes[K] = scilabSparse.icol[K] - 1;
262         }
263
264         if (scilabSparse.it == 0) /* Real sparse */
265         {
266             if ((data = (double*) MALLOC(sizeof(double) * scilabSparse.nel)) == NULL)
267             {
268                 Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
269                 FREE(rowIndexes);
270                 FREE(colIndexes);
271                 if (scilabSparse.it)
272                 {
273                     freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
274                 }
275                 else
276                 {
277                     freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
278                 }
279
280                 return 0;
281             }
282
283             for (K = 0; K < scilabSparse.nel; K++)
284             {
285                 data[K] = scilabSparse.R[K];
286             }
287         }
288         else
289         {
290             if ((data = (double*) MALLOC(2 * sizeof(double) * scilabSparse.nel)) == NULL)
291             {
292                 Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
293                 FREE(rowIndexes);
294                 FREE(colIndexes);
295                 if (scilabSparse.it)
296                 {
297                     freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
298                 }
299                 else
300                 {
301                     freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
302                 }
303
304                 return FALSE;
305             }
306
307             for (K = 0; K < scilabSparse.nel; K++)
308             {
309                 data[K] = scilabSparse.R[K];
310             }
311
312             for (K = 0; K < scilabSparse.nel; K++)
313             {
314                 data[K + scilabSparse.nel] = scilabSparse.I[K];
315             }
316         }
317
318         /* Create Matlab Sparse matrix data */
319         sparseData->nzmax = scilabSparse.nel;
320         sparseData->nir   = scilabSparse.nel;
321         sparseData->ir    = rowIndexes;
322         /* sparseData->njc   = scilabSparse.nel + 1; */
323         sparseData->njc   = scilabSparse.m + 1;
324         sparseData->jc    = colIndexes;
325         sparseData->ndata = scilabSparse.nel;
326         sparseData->data  = (void*) data;
327
328         pszDims = (size_t*) MALLOC(rank * sizeof(size_t));
329         if (pszDims == NULL)
330         {
331             Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
332
333             if (scilabSparse.it)
334             {
335                 freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
336             }
337             else
338             {
339                 freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
340             }
341
342             return 0;
343         }
344
345         for (K = 0; K < rank; K++)
346         {
347             pszDims[K] = dims[K];
348         }
349
350         if (scilabSparse.it == 0)
351         {
352             createdVar = Mat_VarCreate(name, MAT_C_SPARSE, MAT_T_DOUBLE, rank, pszDims, sparseData, 0 | MAT_F_DONT_COPY_DATA);
353         }
354         else
355         {
356             createdVar = Mat_VarCreate(name, MAT_C_SPARSE, MAT_T_DOUBLE, rank, pszDims, sparseData, MAT_F_COMPLEX | MAT_F_DONT_COPY_DATA);
357
358             if (data)
359             {
360                 FREE(data);
361             }
362         }
363
364         if (dims)
365         {
366             FREE(dims);
367         }
368
369         if (pszDims)
370         {
371             FREE(pszDims);
372         }
373     }
374     else
375     {
376         Scierror(999, _("%s: Wrong type for first input argument: Sparse matrix expected.\n"), "GetSparseVariable");
377     }
378
379     if (scilabSparse.it)
380     {
381         freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
382     }
383     else
384     {
385         freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
386     }
387
388     return createdVar;
389 }