linear_algebra plugged.
[scilab.git] / scilab / modules / linear_algebra / sci_gateway / cpp / sci_det.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - DIGITEO - Cedric DELAMARRE
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
14 #include "linear_algebra_gw.hxx"
15 #include "function.hxx"
16 #include "double.hxx"
17 #include "overload.hxx"
18 #include "execvisitor.hxx"
19
20 extern "C"
21 {
22 #include "localization.h"
23 #include "Scierror.h"
24 #include "det.h"
25 }
26 /*--------------------------------------------------------------------------*/
27
28 types::Function::ReturnValue sci_det(types::typed_list &in, int _iRetCount, types::typed_list &out)
29 {
30     types::Double* pDbl             = NULL;
31     types::Double* pDblMantissa     = NULL;
32     types::Double* pDblExponent     = NULL;
33     double* pData                   = NULL;
34
35     if(in.size() != 1)
36     {
37         ScierrorW(77, _W("%ls: Wrong number of input argument(s): %d expected.\n"), L"det", 1);
38         return types::Function::Error;
39     }
40
41     if(_iRetCount > 2)
42     {
43         ScierrorW(78, _W("%ls: Wrong number of output argument(s): %d to %d expected.\n"), L"det", 1, 2);
44         return types::Function::Error;
45     }
46
47     if((in[0]->isDouble() == false))
48     {
49         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_det";
50         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
51     }
52
53     pDbl = in[0]->getAs<types::Double>()->clone()->getAs<types::Double>();
54
55     if(pDbl->isComplex())
56     {
57         pData = (double *)oGetDoubleComplexFromPointer(pDbl->getReal(), pDbl->getImg(), pDbl->getSize());
58         if(!pData)
59         {
60             ScierrorW(999,_W("%ls: Cannot allocate more memory.\n"),L"det");
61             return types::Function::Error;
62         }
63     }
64     else
65     {
66         pData = pDbl->getReal();
67     }
68
69     if(pDbl->getRows() != pDbl->getCols())
70     {
71         ScierrorW(20, _W("%ls: Wrong type for argument %d: Square matrix expected.\n"), L"det", 1);
72         return types::Function::Error;
73     }
74
75     if((pDbl->getRows() == -1)) // manage eye case
76     {
77         ScierrorW(271,_W("%ls: Size varying argument a*eye(), (arg %d) not allowed here.\n"), L"det", 1);
78         return types::Function::Error;
79     }
80
81     if(pDbl->getCols() == -1)
82     {
83         types::Double* pDblEyeMatrix = new types::Double(-1, -1);
84         out.push_back(pDblEyeMatrix);
85         return types::Function::Error;
86     }
87
88     if(pDbl->isComplex())
89     {
90         pData = (double *)oGetDoubleComplexFromPointer(pDbl->getReal(), pDbl->getImg(), pDbl->getSize());
91         if(!pData)
92         {
93             ScierrorW(999,_W("%ls: Cannot allocate more memory.\n"),L"det");
94             return types::Function::Error;
95         }
96     }
97     else
98     {
99         pData = pDbl->getReal();
100     }
101
102     pDblMantissa = new types::Double(1, 1, pDbl->isComplex());
103
104     if(_iRetCount == 2)
105     {
106         pDblExponent = new types::Double(1,1);
107     }
108
109     int iExponent = 0;
110     int iRet= iDetM(pData, pDbl->getCols(), pDblMantissa->getReal(), pDbl->isComplex() ? pDblMantissa->getImg() : NULL, pDblExponent ? &iExponent : NULL);
111     if(iRet != 0)
112     {
113             ScierrorW(999, _W("%ls: LAPACK error n°%d.\n"), L"det",iRet);
114         return types::Function::Error;
115     }
116
117     if(pDblExponent)
118     {
119         pDblExponent->set(0, iExponent);
120     }
121
122     if(pDbl->isComplex())
123     {
124         vFreeDoubleComplexFromPointer((doublecomplex*)pData);
125     }
126
127     if(_iRetCount == 2)
128     {
129         out.push_back(pDblExponent);
130     }
131
132     out.push_back(pDblMantissa);
133
134     return types::Function::OK;
135 }
136 /*--------------------------------------------------------------------------*/
137