2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-2010 - DIGITEO - Bernard HUGUENEY
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
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.
18 #include "sparse_gw.hxx"
19 #include "function.hxx"
25 #include "charEncoding.h"
27 #include "localization.h"
30 types::Function::ReturnValue sci_sparse(types::typed_list &in, int _piRetCount, types::typed_list &out)
33 types::GenericType* pRetVal = NULL;
35 // per the scilab manual sparse will take upto 3 arguments but no less than one
36 if (in.size() < 1 || in.size() > 3)
38 Scierror(999, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "sparse", 1, 3);
39 return types::Function::Error;
42 for (int i = 0 ; isValid && i < in.size() ; i++)
44 // Valid input arguments are of Bool and Double types (dense or sparse)
45 switch (in[i]->getType())
47 case types::InternalType::ScilabBool :
48 case types::InternalType::ScilabSparseBool :
50 isValid = (i == (in.size() > 1 ? 1 : 0));
52 case types::InternalType::ScilabDouble :
53 case types::InternalType::ScilabSparse :
65 Scierror(999, _("%s: Wrong type for input argument #%d: Matrix expected.\n"), "sparse", i + 1);
66 return types::Function::Error;
69 // Valid input arguments are matrices and not hypermatrices
70 if ( in[i]->getAs<types::GenericType>()->getDims() > 2 )
72 Scierror(999, _("%s: Wrong size for input argument #%d: A m-by-n matrix expected.\n"), "sparse", i + 1);
73 return types::Function::Error;
77 // if one argument is given, it will be a matrix of constant or sparse type, which will be converted into a sparse matrix
80 switch (in[0]->getType())
82 case types::InternalType::ScilabSparse :
84 pRetVal = new types::Sparse(*in[0]->getAs<types::Sparse>());
87 case types::InternalType::ScilabDouble :
89 if (in[0]->getAs<types::Double>()->isEmpty())
91 out.push_back(types::Double::Empty());
92 return types::Function::OK;
95 if (in[0]->getAs<types::Double>()->isIdentity())
98 return types::Function::OK;
101 pRetVal = new types::Sparse(*in[0]->getAs<types::Double>());
104 case types::InternalType::ScilabBool :
106 pRetVal = new types::SparseBool(*in[0]->getAs<types::Bool>());
109 case types::InternalType::ScilabSparseBool :
111 pRetVal = new types::SparseBool(*in[0]->getAs<types::SparseBool>());
120 else // 2 or 3 arguments
122 types::Double* pDij = in[0]->getAs<types::Double>(); // arg 2 necessarily *Double
123 types::GenericType* pGT2 = in[1]->getAs<types::GenericType>();
124 int size = pGT2->getSize();
126 if ( ((size !=0) || (pDij->getSize() != 0)) && ((pDij->getCols() != 2) || (pDij->getRows() != size)))
130 Scierror(999, _("%s: Wrong size for input argument #%d: A matrix of size %d x %d expected.\n"), "sparse", 1, size, 2);
134 Scierror(999, _("%s: Wrong size for input argument #%d: An empty matrix expected.\n"), "sparse", 1);
136 return types::Function::Error;
139 //Double* pDdims( (in.size()==3) ? in[2]->getAs<Double>() : 0);
140 types::Double* pDdims = NULL;
143 pDdims = in[2]->getAs<types::Double>();
144 if (pDdims->getSize() != 2)
146 Scierror(999, _("%s: Wrong size for input argument #%d: A matrix of size %d x %d expected.\n"), "sparse", 3, 1, 2);
147 return types::Function::Error;
150 if (pDdims->get(0) != (double) ( (unsigned int) pDdims->get(0) ) || pDdims->get(1) != (double) ( (unsigned int) pDdims->get(1) ))
152 Scierror(999, _("%s: Wrong values for input argument #%d: Positive integers expected.\n"), "sparse", 3);
153 return types::Function::Error;
158 double* pdbli = pDij->get();
159 double* pdblj = pdbli + size;
161 for (int i = 0; i < 2*size; i++)
163 pdbli[i] = trunc(pdbli[i]);
166 if ( (size > 0) && ((*std::min_element(pdbli, pdbli + size) <= 0) || (*std::min_element(pdblj, pdblj + size) <= 0)) )
168 Scierror(999, _("%s: Invalid index.\n"), "sparse");
169 return types::Function::Error;
172 if (pDdims == nullptr)
174 pDdims = new types::Double(1, 2, false);
178 pDdims->set(0, *std::max_element(pdbli, pdbli + size));
179 pDdims->set(1, *std::max_element(pdblj, pdblj + size));
183 else if ( (size > 0) && ((pDdims->get(0) < *std::max_element(pdbli, pdbli + size))
184 || (pDdims->get(1) < *std::max_element(pdblj, pdblj + size))) )
186 Scierror(999, _("%s: Invalid index.\n"),"sparse");
187 return types::Function::Error;
190 if ((pDdims->get(0) == 0) || (pDdims->get(1) == 0))
192 pRetVal = new types::Sparse(0,0,false);
194 else if (in[1]->isDouble())
196 types::Double* pDbl = pGT2->getAs<types::Double>();
197 pRetVal = new types::Sparse(*pDbl, *pDij, *pDdims);
201 types::Bool* pBb = pGT2->getAs<types::Bool>();
202 pRetVal = new types::SparseBool(*pBb, *pDij, *pDdims);
213 return types::Function::Error;
216 out.push_back(pRetVal);
217 return types::Function::OK;