1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-2010 - DIGITEO - Bernard HUGUENEY
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 "sparse_gw.hxx"
17 #include "function.hxx"
18 #include "sparse.hxx"
19 #include "gsort.hxx"
20
21 extern "C"
22 {
23 #include "charEncoding.h"
24 #include "Scierror.h"
25 #include "localization.h"
26 }
27
sci_spget(types::typed_list & in,int _iRetCount,types::typed_list & out)28 types::Function::ReturnValue sci_spget(types::typed_list &in, int _iRetCount, types::typed_list &out)
29 {
30 types::Double* pValues = NULL;
31 types::Double* pCoordSorted = NULL;
32 types::Bool* pBools = NULL;
33
34 int iRows = 0;
35 int iCols = 0;
36 bool bComplex = false;
37 int nonZeros = 0;
38 int* pRows = NULL;
39 double* pNonZeroR = NULL;
40 double* pNonZeroI = NULL;
41
42 if (in.size() != 1)
43 {
44 Scierror(999, _("%s: Wrong number of input argument(s): %d expected.\n"), "spget", 1);
45 return types::Function::Error;
46 }
47
48 if (in[0]->isSparse())
49 {
50 types::Sparse* sp = in[0]->getAs<types::Sparse>();
51 nonZeros = static_cast<int>(sp->nonZeros());
52
53 if (nonZeros == 0)
54 {
55 out.push_back(types::Double::Empty());
56 if (_iRetCount > 1)
57 {
58 out.push_back(types::Double::Empty());
59 }
60
61 if (_iRetCount > 2)
62 {
63 types::Double* pSize = new types::Double(1, 2);
64 pSize->set(0, sp->getRows());
65 pSize->set(1, sp->getCols());
66 out.push_back(pSize);
67 }
68
69 return types::Function::OK;
70 }
71
72 pRows = new int[nonZeros * 2];
73 sp->outputRowCol(pRows);
74
75 if (_iRetCount > 1)
76 {
77 pNonZeroR = new double[nonZeros];
78 pNonZeroI = new double[nonZeros];
79 sp->outputValues(pNonZeroR, pNonZeroI);
80 }
81
82 iRows = sp->getRows();
83 iCols = sp->getCols();
84 bComplex = sp->isComplex();
85
86 pValues = new types::Double(nonZeros, 1, bComplex);
87
88 }
89 else if (in[0]->isSparseBool())
90 {
91 types::SparseBool* sp = in[0]->getAs<types::SparseBool>();
92 nonZeros = static_cast<int>(sp->nbTrue());
93
94 if (nonZeros == 0)
95 {
96 out.push_back(types::Double::Empty());
97 if (_iRetCount > 1)
98 {
99 out.push_back(types::Double::Empty());
100 }
101
102 if (_iRetCount > 2)
103 {
104 types::Double* pSize = new types::Double(1, 2);
105 pSize->set(0, sp->getRows());
106 pSize->set(1, sp->getCols());
107 out.push_back(pSize);
108 }
109
110 return types::Function::OK;
111 }
112
113
114 pRows = new int[nonZeros * 2];
115 sp->outputRowCol(pRows);
116
117 iRows = sp->getRows();
118 iCols = sp->getCols();
119
120 pBools = new types::Bool(nonZeros, 1);
121 }
122 else
123 {
124 Scierror(999, _("%s: Wrong type for input argument #%d: sparse matrix expected.\n"), "spget", 1);
125 return types::Function::Error;
126 }
127
128 if (_iRetCount > 3)
129 {
130 Scierror(999, _("%s: Wrong number of output arguments: %d to %d expected.\n"), "spget", 1, 3);
131 delete[] pRows;
132 delete[] pNonZeroR;
133 delete[] pNonZeroI;
134 if (pBools)
135 {
136 pBools->killMe();
137 }
138 if (pValues)
139 {
140 pValues->killMe();
141 }
142 return types::Function::Error;
143 }
144
145 types::Double* pCoord = new types::Double(nonZeros, 2);
146 pCoord->setInt(pRows);
147
148 if (_iRetCount > 1)
149 {
150 if (pBools)
151 {
152 pCoordSorted = gsort(pCoord, NULL, L"i", L"lr");
153 for (int i = 0 ; i < nonZeros ; i++)
154 {
155 pBools->set(i, true);
156 }
157 }
158 else
159 {
160 types::Double* pIndex = new types::Double(nonZeros, 1);
161 pCoordSorted = gsort(pCoord, pIndex, L"i", L"lr");
162 if (pValues->isComplex())
163 {
164 for (int i = 0 ; i < nonZeros ; i++)
165 {
166 pValues->set(i, pNonZeroR[(int)pIndex->get(i) - 1]);
167 pValues->setImg(i, pNonZeroI[(int)pIndex->get(i) - 1]);
168 }
169 }
170 else
171 {
172 for (int i = 0 ; i < nonZeros ; i++)
173 {
174 pValues->set(i, pNonZeroR[(int)pIndex->get(i) - 1]);
175 }
176 }
177
178 delete[] pNonZeroR;
179 delete[] pNonZeroI;
180 delete pIndex;
181 }
182 }
183 else
184 {
185 pCoordSorted = gsort(pCoord, NULL, L"i", L"lr");
186 }
187
188 out.push_back(pCoordSorted);
189 if (_iRetCount > 1)
190 {
191 if (pBools)
192 {
193 out.push_back(pBools);
194 }
195 else
196 {
197 out.push_back(pValues);
198 }
199 }
200 else
201 {
202 if (pBools)
203 {
204 pBools->killMe();
205 }
206
207 if (pValues)
208 {
209 pValues->killMe();
210 }
211 }
212
213 if (_iRetCount > 2)
214 {
215 types::Double* pSize = new types::Double(1, 2);
216 pSize->set(0, iRows);
217 pSize->set(1, iCols);
218 out.push_back(pSize);
219 }
220
221 delete pCoord;
222 delete[] pRows;
223 return types::Function::OK;
224 }
225