linear_algebra plugged.
[scilab.git] / scilab / modules / linear_algebra / sci_gateway / cpp / sci_balanc.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2009 - DIGITEO - Bernard HUGUENEY
4 * Copyright (C) 2011 - DIGITEO - Cedric DELAMARRE
5 *
6 * This file must be used under the terms of the CeCILL.
7 * This source file is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution.  The terms
9 * are also available at
10 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11 *
12 */
13 /*--------------------------------------------------------------------------*/
14
15 #include "linear_algebra_gw.hxx"
16 #include "function.hxx"
17 #include "double.hxx"
18 #include "overload.hxx"
19 #include "execvisitor.hxx"
20
21 extern "C"
22 {
23 #include "localization.h"
24 #include "Scierror.h"
25 #include "balanc.h"
26 }
27 /*--------------------------------------------------------------------------*/
28
29 types::Function::ReturnValue sci_balanc(types::typed_list &in, int _iRetCount, types::typed_list &out)
30 {
31     types::Double* pDbl[2]      = {NULL, NULL};
32     types::Double* pDblRes[2]   = {NULL, NULL};
33     double* pData[2]            = {NULL, NULL};
34     bool bComplex               = false;
35
36     if(in.size() != 1 && in.size() != 2)
37     {
38         ScierrorW(77, _W("%ls: Wrong number of input argument(s): %d to %d expected.\n"), L"balanc", 1, 2);
39         return types::Function::Error;
40     }
41
42     if(_iRetCount != 2*in.size())
43     {
44         ScierrorW(78, _W("%ls: Wrong number of output argument(s): %d expected.\n"), L"balanc", 2*in.size());
45         return types::Function::Error;
46     }
47
48     if((in[0]->isDouble() == false))
49     {
50         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_balanc";
51         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
52     }
53
54     pDbl[0] = in[0]->getAs<types::Double>()->clone()->getAs<types::Double>();
55     if(pDbl[0]->isComplex())
56     {
57         bComplex = true;
58     }
59
60     if(in.size() == 2)
61     {
62         if((in[1]->isDouble() == false))
63         {
64             std::wstring wstFuncName = L"%"  + in[1]->getShortTypeStr() + L"_balanc";
65             return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
66         }
67
68         pDbl[1] = in[1]->getAs<types::Double>()->clone()->getAs<types::Double>();
69         if(pDbl[1]->isComplex())
70         {
71             bComplex = true;
72         }
73
74         if(pDbl[0]->getRows() != pDbl[1]->getRows())
75         {
76             ScierrorW(999, _W("%ls: Arguments %d and %d must have equal dimensions.\n"), L"balanc", 1, 2);
77             return types::Function::Error;
78         }
79     }
80
81     if(pDbl[0]->getCols() == 0)
82     {
83         out.push_back(types::Double::Empty());
84         out.push_back(types::Double::Empty());
85         if(_iRetCount == 4)
86         {
87             out.push_back(types::Double::Empty());
88             out.push_back(types::Double::Empty());
89         }
90         return types::Function::OK;
91     }
92
93     if(pDbl[0]->getRows() != pDbl[0]->getCols())
94     {
95         ScierrorW(20, _W("%ls: Wrong type for argument %d: Square matrix expected.\n"), L"balanc", 1);
96         return types::Function::Error;
97     }
98
99     for(int i=0; i<in.size(); i++)
100     {
101         if(bComplex)
102         {
103             pData[i] = (double*)oGetDoubleComplexFromPointer(pDbl[i]->getReal(), pDbl[i]->getImg(), pDbl[i]->getSize());
104             if(!pData[i])
105             {
106                 ScierrorW(999,_W("%ls: Cannot allocate more memory.\n"),L"balanc");
107                 return types::Function::Error;
108             }
109         }
110         else
111         {
112             pData[i] = pDbl[i]->getReal();
113         }
114
115         pDblRes[i] = new types::Double(pDbl[i]->getRows(), pDbl[i]->getCols());
116     }
117
118     int iRet = iBalancM(pData[0], pData[1], pDbl[0]->getCols(), bComplex, pDblRes[0]->get(), ( pDblRes[1] ? pDblRes[1]->get() : NULL));
119
120     if(iRet != 0)
121     {
122             ScierrorW(999, _W("%ls: LAPACK error n°%d.\n"), L"balanc",iRet);
123         return types::Function::Error;
124     }
125
126     if(bComplex)
127     {
128         for(int i=0; i<in.size(); i++)
129         {
130             vGetPointerFromDoubleComplex((doublecomplex*)pData[i], pDbl[i]->getSize(), pDbl[i]->getReal(), pDbl[i]->getImg());
131             vFreeDoubleComplexFromPointer((doublecomplex*)pData[i]);
132         }
133     }
134
135     if(_iRetCount == 2)
136     {
137         out.push_back(pDbl[0]);
138         out.push_back(pDblRes[0]);
139     }
140     else //_iRetCount == 4
141     {
142         out.push_back(pDbl[0]);
143         out.push_back(pDbl[1]);
144         out.push_back(pDblRes[0]);
145         out.push_back(pDblRes[1]);
146     }
147
148     return types::Function::OK;
149 }
150 /*--------------------------------------------------------------------------*/
151