2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - Cedric DELAMARRE
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.
15 /*--------------------------------------------------------------------------*/
16 #include "polynomials_gw.hxx"
17 #include "function.hxx"
19 #include "polynom.hxx"
20 #include "overload.hxx"
25 #include "localization.h"
27 #include "elem_common.h"
28 extern int C2F(sfact1)(double*, int*, double*, int*, int*);
29 extern int C2F(sfact2)(double*, int*, int*, double*, int*, int*);
31 /*--------------------------------------------------------------------------*/
32 types::Function::ReturnValue sci_sfact(types::typed_list &in, int _iRetCount, types::typed_list &out)
34 types::Polynom* pPolyIn = NULL;
35 types::Polynom* pPolyOut = NULL;
43 Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "sfact", 1);
44 return types::Function::Error;
49 Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "sfact", 1);
50 return types::Function::Error;
53 if (in[0]->isPoly() == false)
55 std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_sfact";
56 return Overload::call(wstFuncName, in, _iRetCount, out);
59 pPolyIn = in[0]->getAs<types::Polynom>();
61 if (pPolyIn->isComplex())
63 Scierror(999, _("%s: Wrong value for input argument #%d: A real matrix expected.\n"), "sfact", 1);
64 return types::Function::Error;
67 if (pPolyIn->isScalar())
69 double* pdblCoef = pPolyIn->get(0)->get();
72 int iDegree = pPolyIn->get(0)->getRank();
73 int iDegD2 = (int)(iDegree / 2);
76 if (2 * iDegD2 != iDegree)
78 Scierror(999, _("%s: Wrong value for input argument #%d: A symmetric polynomial expected.\n"), "sfact", 1);
79 return types::Function::Error;
82 for (int i = 0; i < n; i++)
84 if (pdblCoef[i] != pdblCoef[iDegree - i])
86 Scierror(999, _("%s: Wrong value for input argument #%d: A symmetric polynomial expected.\n"), "sfact", 1);
87 return types::Function::Error;
92 pPolyOut = new types::Polynom(pPolyIn->getVariableName(), 1, 1);
93 double* pdblCoefOut = NULL;
94 types::SinglePoly* pSP = new types::SinglePoly(&pdblCoefOut, iDegD2);
95 C2F(dcopy)(&n, pdblCoef, &iOne, pdblCoefOut, &iOne);
98 double* pdblWork = new double[7 * n];
99 C2F(sfact1)(pdblCoefOut, &iDegD2, pdblWork, &iMaxIt, &iErr);
105 Scierror(999, _("%s: Wrong value for input argument #%d: Non negative or null value expected at degree %d.\n"), "sfact", 1, n);
106 return types::Function::Error;
112 Scierror(999, _("%s: Wrong value for input argument #%d: Convergence problem.\n"), "sfact", 1);
113 return types::Function::Error;
117 sciprint("%s: warning: Convergence at 10^%d near.\n", "sfact", iErr);
121 pPolyOut->set(0, pSP);
126 if (pPolyIn->getRows() != pPolyIn->getCols())
128 Scierror(999, _("%s: Wrong size for input argument #%d: Square matrix expected.\n"), "sfact", 1);
129 return types::Function::Error;
132 int iSize = pPolyIn->getSize();
133 int iRows = pPolyIn->getRows();
134 int iDegree = pPolyIn->getMaxRank();
135 int iDegD2 = (int)(iDegree / 2);
138 double* pdblOut = new double[iSize * n];
139 double* pdblWork = new double[(n + 1) * iRows * ((n + 1)*iRows) + 1];
141 memset(pdblOut, 0x00, iSize * n * sizeof(double));
143 for (int i = 0; i < iSize; i++)
145 double* pdblIn = pPolyIn->get(i)->get();
146 int iSizeToCpy = 2 + pPolyIn->get(i)->getSize() - 1 - n;
149 C2F(dcopy)(&iSizeToCpy, pdblIn + n - 1, &iOne, pdblOut + i, &iSize);
155 C2F(sfact2)(pdblOut, &iRows, &nm1, pdblWork, &iMaxIt, &iErr);
161 Scierror(999, _("%s: Wrong value for input argument #%d: Convergence problem.\n"), "sfact", 1);
162 return types::Function::Error;
167 Scierror(999, _("%s: Wrong value for input argument #%d: singular or asymmetric problem.\n"), "sfact", 1);
168 return types::Function::Error;
171 pPolyOut = new types::Polynom(pPolyIn->getVariableName(), pPolyIn->getDims(), pPolyIn->getDimsArray());
172 for (int i = 0; i < iSize; i++)
174 double* pdblCoefOut = NULL;
175 types::SinglePoly* pSP = new types::SinglePoly(&pdblCoefOut, nm1);
176 C2F(dcopy)(&n, pdblOut + i, &iSize, pdblCoefOut, &iOne);
177 pPolyOut->set(i, pSP);
184 out.push_back(pPolyOut);
185 return types::Function::OK;
187 /*--------------------------------------------------------------------------*/