c738b9ad639da9990498d381ef6465f75d1ef94a
[scilab.git] / scilab / modules / ast / src / cpp / operations / types_ldivide.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2013 - Scilab Enterprises - 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 #include "types_ldivide.hxx"
14 #include "types_divide.hxx"
15 #include "types_finite.hxx"
16
17 #include "scilabexception.hxx"
18
19 extern "C"
20 {
21 #include "matrix_left_division.h"
22 #include "sciprint.h"
23 #include "localization.h"
24 #include "charEncoding.h"
25 }
26
27 using namespace types;
28
29 InternalType *GenericLDivide(InternalType *_pLeftOperand, InternalType *_pRightOperand)
30 {
31     InternalType *pResult       = NULL;
32     GenericType::ScilabType TypeL = _pLeftOperand->getType();
33     GenericType::ScilabType TypeR = _pRightOperand->getType();
34
35     int iResult = 0;
36
37     if (_pLeftOperand->isDouble() && _pLeftOperand->getAs<Double>()->isEmpty())
38     {
39         return Double::Empty();
40     }
41
42     if (_pRightOperand->isDouble() && _pRightOperand->getAs<Double>()->isEmpty())
43     {
44         return Double::Empty();
45     }
46
47     /*
48     ** DOUBLE \ DOUBLE
49     */
50     if (TypeL == GenericType::ScilabDouble && TypeR == GenericType::ScilabDouble)
51     {
52         Double *pL  = _pLeftOperand->getAs<Double>();
53         Double *pR  = _pRightOperand->getAs<Double>();
54
55         iResult = LDivideDoubleByDouble(pL, pR, (Double**)&pResult);
56     }
57
58     //manage errors
59     if (iResult)
60     {
61         switch (iResult)
62         {
63             case 1 :
64                 throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
65             case 2 :
66                 throw ast::ScilabError(_W("With NaN or Inf a left division by scalar expected.\n"));
67             case 3 :
68                 throw ast::ScilabError(_W("Left division by zero...\n"));
69             case 4 :
70                 sciprint(_("Warning : Left division by zero...\n"));
71                 break;
72             default :
73                 sciprint(_("Operator \\ : Error %d not yet managed.\n"), iResult);
74         }
75     }
76
77     /*
78     ** Default case : Return NULL will Call Overloading.
79     */
80     return pResult;
81 }
82
83 int LDivideDoubleByDouble(Double *_pDouble1, Double *_pDouble2, Double **_pDoubleOut)
84 {
85     int iErr = 0;
86
87     //check finite values of _pDouble1 and _pDouble2
88     if (isDoubleFinite(_pDouble1) == false || isDoubleFinite(_pDouble2) == false)
89     {
90         if (_pDouble2->isScalar() == false)
91         {
92             return 2;
93         }
94     }
95
96     if (_pDouble1->isScalar())
97     {
98         //Y \ x => x / Y
99         return RDivideDoubleByDouble(_pDouble2, _pDouble1, _pDoubleOut);
100     }
101
102     if (_pDouble2->isScalar())
103     {
104         // managed in %s_l_s, call overload
105         return 0;
106     }
107
108     if (_pDouble1->getDims() > 2 || _pDouble2->getDims() > 2 || _pDouble1->getRows() != _pDouble2->getRows())
109     {
110         //not managed
111         return 1;
112     }
113
114     *_pDoubleOut = new Double(_pDouble1->getCols(), _pDouble2->getCols(), _pDouble1->isComplex() || _pDouble2->isComplex());
115     if ((*_pDoubleOut)->isComplex())
116     {
117         double dblRcond = 0;
118         iErr = iLeftDivisionOfComplexMatrix(
119                    _pDouble1->getReal(), _pDouble1->getImg(), _pDouble1->getRows(), _pDouble1->getCols(),
120                    _pDouble2->getReal(), _pDouble2->getImg(), _pDouble2->getRows(), _pDouble2->getCols(),
121                    (*_pDoubleOut)->getReal(), (*_pDoubleOut)->getImg(), (*_pDoubleOut)->getRows(), (*_pDoubleOut)->getCols(), &dblRcond);
122     }
123     else
124     {
125         double dblRcond = 0;
126         iErr = iLeftDivisionOfRealMatrix(
127                    _pDouble1->getReal(), _pDouble1->getRows(), _pDouble1->getCols(),
128                    _pDouble2->getReal(), _pDouble2->getRows(), _pDouble2->getCols(),
129                    (*_pDoubleOut)->getReal(), (*_pDoubleOut)->getRows(), (*_pDoubleOut)->getCols(), &dblRcond);
130     }
131
132     return iErr;
133 }
134