2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - DIGITEO - 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 /*--------------------------------------------------------------------------*/
17 #include "linear_algebra_gw.hxx"
18 #include "function.hxx"
20 #include "overload.hxx"
24 #include "localization.h"
27 #include "doublecomplex.h"
29 /*--------------------------------------------------------------------------*/
31 types::Function::ReturnValue sci_lsq(types::typed_list &in, int _iRetCount, types::typed_list &out)
33 types::Double* pDbl[2] = {NULL, NULL};
34 types::Double* pDblResult = NULL;
35 double* pData[2] = {NULL, NULL};
36 double* pResult = NULL;
38 bool bComplexArgs = false;
42 if (in.size() < 2 || in.size() > 3)
44 Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "lsq", 2, 3);
45 return types::Function::Error;
50 Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected.\n"), "lsq", 1, 2);
51 return types::Function::Error;
54 if ((in[0]->isDouble() == false))
56 std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_lsq";
57 return Overload::call(wstFuncName, in, _iRetCount, out);
62 if ((in[1]->isDouble() == false))
64 std::wstring wstFuncName = L"%" + in[1]->getShortTypeStr() + L"_lsq";
65 return Overload::call(wstFuncName, in, _iRetCount, out);
71 if ((in[2]->isDouble() == false) || (in[2]->getAs<types::Double>()->isComplex()) || (in[2]->getAs<types::Double>()->isScalar() == false))
73 Scierror(256, _("%s: Wrong type for input argument #%d: A Real expected.\n"), "lsq", 3);
74 return types::Function::Error;
77 dblTol = in[2]->getAs<types::Double>()->get(0);
81 pDbl[0] = in[0]->getAs<types::Double>();
82 pDbl[1] = in[1]->getAs<types::Double>();
84 if (pDbl[0]->getRows() != pDbl[1]->getRows())
86 Scierror(265, _("%s: %s and %s must have equal number of rows.\n"), "lsq", "A", "B");
87 return types::Function::Error;
90 if ((pDbl[0]->getCols() == 0) || (pDbl[1]->getCols() == 0))
92 out.push_back(types::Double::Empty());
95 out.push_back(types::Double::Empty());
97 return types::Function::OK;
100 if (pDbl[0]->isComplex() || pDbl[1]->isComplex())
105 pDbl[0] = pDbl[0]->clone();
106 pDbl[1] = pDbl[1]->clone();
108 for (int i = 0; i < 2; i++)
110 if (pDbl[i]->getCols() == -1)
112 for (int j=0; j<=i; j++)
116 Scierror(271, _("%s: Size varying argument a*eye(), (arg %d) not allowed here.\n"), "lsq", i + 1);
117 return types::Function::Error;
122 pData[i] = (double*)oGetDoubleComplexFromPointer(pDbl[i]->getReal(), pDbl[i]->getImg(), pDbl[i]->getSize());
125 for (int j=0; j<=i; j++)
129 Scierror(999, _("%s: Cannot allocate more memory.\n"), "lsq");
130 return types::Function::Error;
135 pData[i] = pDbl[i]->getReal();
139 pDblResult = new types::Double(pDbl[0]->getCols(), pDbl[1]->getCols(), bComplexArgs);
143 pResult = (double*)MALLOC(pDbl[0]->getCols() * pDbl[1]->getCols() * sizeof(doublecomplex));
147 pResult = pDblResult->get();
150 int iRet = iLsqM(pData[0], pDbl[0]->getRows(), pDbl[0]->getCols(), pData[1], pDbl[1]->getCols(), bComplexArgs, pResult, pdTol, ((_iRetCount == 2) ? &iRank : NULL));
159 Scierror(999, _("%s: Allocation failed.\n"), "lsq");
163 Scierror(999, _("%s: LAPACK error n°%d.\n"), "lsq", iRet);
168 vFreeDoubleComplexFromPointer((doublecomplex*)pResult);
169 vFreeDoubleComplexFromPointer((doublecomplex*)pData[0]);
170 vFreeDoubleComplexFromPointer((doublecomplex*)pData[1]);
172 pDblResult->killMe();
173 return types::Function::Error;
178 vGetPointerFromDoubleComplex((doublecomplex*)(pResult), pDblResult->getSize(), pDblResult->getReal(), pDblResult->getImg());
179 vFreeDoubleComplexFromPointer((doublecomplex*)pResult);
180 vFreeDoubleComplexFromPointer((doublecomplex*)pData[0]);
181 vFreeDoubleComplexFromPointer((doublecomplex*)pData[1]);
184 out.push_back(pDblResult);
187 types::Double* pDblRank = new types::Double(1, 1);
188 pDblRank->set(0, iRank);
189 out.push_back(pDblRank);
192 return types::Function::OK;
194 /*--------------------------------------------------------------------------*/