timedvisitor
[scilab.git] / scilab / modules / abstractSyntaxTree / src / cpp / run / run_MatrixExp.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
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 "runvisitor.hxx"
14 #include "execvisitor.hxx"
15 #include "timedvisitor.hxx"
16
17 using std::string;
18
19 InternalType* AddElementToVariable(InternalType* _poDest, InternalType* _poSource, int _iRows, int _iCols, int *_piRows, int *_piCols);
20
21
22 namespace ast
23 {
24         template class RunVisitorT<ExecVisitor>;
25         template class RunVisitorT<TimedVisitor>;
26
27         /*
28         [1,2;3,4] with/without special character $ and :
29         */
30         template <class T>
31         void RunVisitorT<T>::visitprivate(const MatrixExp &e)
32         {
33                 try
34                 {
35 //                      int iRows = e.lines_get().size();
36 //                      int iCols       = -1;
37                         int iRows = 0;
38                         int iCols       = -1;
39                         int iCurRow = -1;
40                         int iCurCol = 0;
41                         InternalType *poResult = NULL;
42
43                         std::list<MatrixLineExp *>::const_iterator      row;
44                         std::list<Exp *>::const_iterator        col;
45                         //store all element after evaluation
46                         if(e.lines_get().size() == 0)
47                         {
48                                 poResult = new Double(0,0);
49                         }
50                         else
51                         {
52                                 list<list<InternalType*> > MatrixList;
53                                 for (row = e.lines_get().begin() ; row != e.lines_get().end() ; ++row )
54                                 {
55                                         list<InternalType*> RowList;
56                                         for (col = (*row)->columns_get().begin() ; col != (*row)->columns_get().end() ; ++col)
57                                         {
58                                                 T* execMe = new T();
59                                                 (*col)->accept (*execMe);
60                                                 if(execMe->result_get()->getType() == InternalType::RealImplicitList)
61                                                 {
62                                                         if(execMe->result_get()->getAsImplicitList()->computable() == true)
63                                                         {
64                                                                 execMe->result_set(execMe->result_get()->getAsImplicitList()->extract_matrix());
65                                                                 iCurCol += ((GenericType*)execMe->result_get())->cols_get();
66                                                         }
67                                                         else
68                                                         {
69                                                                 iCurCol++;
70                                                         }
71                                                 }
72                                                 else
73                                                 {
74                                                         iCurCol += ((GenericType*)execMe->result_get())->cols_get();
75                                                 }
76
77                                                 if(iCurRow == -1)
78                                                 {
79                                                         iCurRow = ((GenericType*)execMe->result_get())->rows_get();
80                                                 }
81                                                 else if(iCurRow != ((GenericType*)execMe->result_get())->rows_get())
82                                                 {
83                                                         std::ostringstream os;
84                                                         os << "inconsistent row/column dimensions";
85                                                         os << ((Location)(*row)->location_get()).location_string_get() << std::endl;
86                                                         throw os.str();
87                                                 }
88
89                                                 InternalType *pResult = execMe->result_get();
90                                                 RowList.push_back(pResult);
91
92                                                 //tips to delete only execvisitor but not data
93                                                 pResult->IncreaseRef();
94                                                 delete execMe;
95                                                 pResult->DecreaseRef();
96                                         }
97
98                                         if(iCols <= 0)
99                                         {
100                                                 iCols = iCurCol;
101                                         }
102                                         else if(iCols != 0 && iCols != iCurCol)
103                                         {
104                                                 std::ostringstream os;
105                                                 os << "inconsistent row/column dimensions";
106                                                 os << ((Location)(*row)->location_get()).location_string_get() << std::endl;
107                                                 throw os.str();
108                                         }
109
110                                         iRows += iCurRow;
111                                         iCurCol = 0;
112                                         iCurRow = -1;
113                                         MatrixList.push_back(RowList);
114                                 }
115
116                                 list<list<InternalType*> >::const_iterator it_ML;
117                                 list<InternalType*>::const_iterator it_RL;
118
119                                 int iAddRow = 0;
120                                 iCurRow                 = 0;
121                                 iCurCol                 = 0;
122                                 for(it_ML = MatrixList.begin() ; it_ML != MatrixList.end() ; it_ML++)
123                                 {
124                                         int iAddCol = 0;
125                                         for(it_RL = (*it_ML).begin() ; it_RL != (*it_ML).end() ; it_RL++)
126                                         {
127                                                 if(poResult == NULL)
128                                                 {
129                                                         poResult = AddElementToVariable(poResult, *it_RL, iRows, iCols, &iAddRow, &iAddCol);
130
131                                                         if((*it_RL)->isDeletable() == true)
132                                                         {
133                                                                 if((*it_RL)->getType() == InternalType::RealDouble)
134                                                                 {
135                                                                         delete (*it_RL)->getAsDouble();
136                                                                 }
137                                                                 else
138                                                                 {
139                                                                         delete (*it_RL);
140                                                                 }
141                                                         }
142                                                         iCurCol += iAddCol;
143                                                 }
144                                                 else
145                                                 {
146                                                         poResult = AddElementToVariable(poResult, *it_RL, iCurRow, iCurCol, &iAddRow, &iAddCol);
147                                                         if((*it_RL)->isDeletable() == true)
148                                                         {
149                                                                 if((*it_RL)->getType() == InternalType::RealDouble)
150                                                                 {
151                                                                         delete (*it_RL)->getAsDouble();
152                                                                 }
153                                                                 else
154                                                                 {
155                                                                         delete (*it_RL);
156                                                                 }
157                                                         }
158                                                         iCurCol += iAddCol;
159                                                 }
160                                         }
161                                         iCurRow += iAddRow;
162                                         iCurCol = 0;
163                                 }
164                         }
165
166                         result_set(poResult);
167                 }
168                 catch(string sz)
169                 {
170                         throw sz;
171                 }
172         }
173 }
174
175
176 /*
177 _iRows : Position if _poDest allready initialized else size of the matrix
178 _iCols : Position if _poDest allready initialized else size of the matrix
179 */
180 InternalType* AddElementToVariable(InternalType* _poDest, InternalType* _poSource, int _iRows, int _iCols, int *_piRows, int *_piCols)
181 {
182         InternalType *poResult  = NULL;
183         InternalType::RealType TypeSource       = ((GenericType*)_poSource)->getType();
184         InternalType::RealType TypeDest         =       InternalType::RealInternal;
185         int iCurRow = _iRows;
186         int iCurCol = _iCols;
187
188         if(_poDest == NULL)
189         {
190                 switch(TypeSource)
191                 {
192                 case GenericType::RealDouble :
193                         poResult = new Double(_iRows, _iCols, false);
194                         break;
195                 case GenericType::RealBool :
196                         poResult = new Bool(_iRows, _iCols);
197                         break;
198                 case GenericType::RealInt :
199                         poResult = Int::createInt(_iRows, _iCols, _poSource->getAsInt()->getIntType());
200                         //poResult = new Int(_iRows, _iCols, _poSource->getAsInt()->getIntType());
201                         break;
202                 case GenericType::RealString :
203                         poResult = new String(_iRows, _iCols);
204                         break;
205                 case GenericType::RealPoly :
206                         {
207                                 int* piRank = new int[_iRows * _iCols];
208                                 for(int i = 0 ; i < _iRows * _iCols ; i++)
209                                 {
210                                         piRank[i] = 1;
211                                 }
212                                 poResult = new MatrixPoly(_poSource->getAsPoly()->var_get(), _iRows, _iCols, piRank);
213                                 break;
214                         }
215                 case InternalType::RealImplicitList :
216                         poResult = new ImplicitList();
217                         break;
218                 }
219                 iCurCol         = 0;
220                 iCurRow         = 0;
221                 TypeDest        =       TypeSource;
222         }
223         else
224         {
225                 TypeDest                = ((GenericType*)_poDest)->getType();
226                 poResult = _poDest;
227         }
228
229
230         if(TypeDest != TypeSource)
231         {//check if source type is compatible with the old one
232                 switch(TypeDest)
233                 {
234                 case GenericType::RealDouble :
235                         if(TypeSource == GenericType::RealPoly)
236                         {
237                                 Double *poDest = (Double*)_poDest;
238                                 //Convert Dest to RealPoly
239                                 int *piRank = new int[poDest->size_get()];
240                                 for(int i = 0 ; i < poDest->size_get() ; i++)
241                                 {
242                                         piRank[i] = 1;
243                                 }
244
245                                 poResult = new MatrixPoly(((MatrixPoly*)_poSource)->var_get(), poDest->rows_get(), poDest->cols_get(),  piRank);
246
247                                 double *pR = poDest->real_get();
248                                 double *pI = poDest->img_get();
249                                 for(int i = 0 ; i < poDest->size_get() ; i++)
250                                 {
251                                         Double *pdbl = NULL;
252                                         if(poDest->isComplex())
253                                         {
254                                                 pdbl = new Double(pR[i], pI[i]);
255                                         }
256                                         else
257                                         {
258                                                 pdbl = new Double(pR[i]);
259                                         }
260
261                                         ((MatrixPoly*)poResult)->poly_set(i, pdbl);
262                                         delete pdbl;
263                                 }
264
265                                 ((MatrixPoly*)poResult)->poly_set(iCurRow, iCurCol, ((MatrixPoly*)_poSource)->poly_get(0)->coef_get());
266                         }
267                         break;
268                 case GenericType::RealPoly :
269                         if(TypeSource == GenericType::RealDouble)
270                         {
271                                 //Add Source like coef of the new element
272                                 Poly* pPolyOut  = poResult->getAsPoly()->poly_get(iCurRow, iCurCol);
273
274                                 pPolyOut->rank_set(1);
275                                 pPolyOut->coef_set((Double*)_poSource);
276                         }
277                         break;
278                 default:
279                         break;
280                 }
281                 return poResult;
282         }
283         else
284         {//Just add the new value in the current item
285                 switch(TypeDest)
286                 {
287                 case GenericType::RealDouble :
288                         if(poResult->getAsDouble()->isComplex() == false && _poSource->getAsDouble()->isComplex() == true)
289                         {
290                                 poResult->getAsDouble()->complex_set(true);
291                         }
292
293                         if(_poSource->getAsDouble()->size_get() != 1)
294                         {
295                                 poResult->getAsDouble()->append(iCurRow, iCurCol, _poSource->getAsDouble());
296                         }
297                         else
298                         {
299                                 poResult->getAsDouble()->val_set(iCurRow, iCurCol, _poSource->getAsDouble()->real_get(0,0), _poSource->getAsDouble()->img_get(0,0));
300                         }
301
302                         *_piRows = _poSource->getAsDouble()->rows_get();
303                         *_piCols = _poSource->getAsDouble()->cols_get();
304                         break;
305                 case GenericType::RealPoly :
306                         {
307                                 if(_poSource->getAsPoly()->isComplex())
308                                 {
309                                         poResult->getAsPoly()->complex_set(true);
310                                 }
311
312                                 if(_poSource->getAsPoly()->size_get() != 1)
313                                 {
314                                         poResult->getAsPoly()->insert(iCurRow, iCurCol, _poSource->getAsPoly());
315                                 }
316                                 else
317                                 {
318                                         Poly* pPolyOut  = poResult->getAsPoly()->poly_get(iCurRow, iCurCol);
319                                         Poly* pPolyIn           = _poSource->getAsPoly()->poly_get(0);
320
321                                         pPolyOut->rank_set(pPolyIn->rank_get());
322                                         pPolyOut->coef_set(pPolyIn->coef_get());
323                                 }
324
325                                 *_piRows = _poSource->getAsPoly()->rows_get();
326                                 *_piCols = _poSource->getAsPoly()->cols_get();
327                                 break;
328                         }
329                 case GenericType::RealBool:
330                         poResult->getAsBool()->bool_set(iCurRow, iCurCol, _poSource->getAsBool()->bool_get(0,0));
331                         *_piRows = _poSource->getAsBool()->rows_get();
332                         *_piCols = _poSource->getAsBool()->cols_get();
333                         break;
334                 case GenericType::RealInt :
335                         //((Double*)poResult)->val_set(iCurRow, iCurCol, ((Double*)_poSource)->real_get(0,0), ((Double*)_poSource)->img_get(0,0));
336                         break;
337                 case GenericType::RealString :
338                         poResult->getAsString()->string_set(iCurRow, iCurCol, _poSource->getAsString()->string_get(0,0));
339                         *_piRows = _poSource->getAsString()->rows_get();
340                         *_piCols = _poSource->getAsString()->cols_get();
341                         break;
342                 case GenericType::RealImplicitList :
343                         {
344                                 if(_poSource->getAsImplicitList()->start_type_get() == InternalType::RealPoly)
345                                 {
346                                         poResult->getAsImplicitList()->start_set(_poSource->getAsImplicitList()->start_get());
347                                 }
348                                 else
349                                 {
350                                         poResult->getAsImplicitList()->start_set(_poSource->getAsImplicitList()->start_get());
351                                 }
352
353                                 if(_poSource->getAsImplicitList()->step_type_get() == InternalType::RealPoly)
354                                 {
355                                         poResult->getAsImplicitList()->step_set(_poSource->getAsImplicitList()->step_get());
356                                 }
357                                 else
358                                 {
359                                         poResult->getAsImplicitList()->step_set(_poSource->getAsImplicitList()->step_get());
360                                 }
361
362                                 if(_poSource->getAsImplicitList()->end_type_get() == InternalType::RealPoly)
363                                 {
364                                         poResult->getAsImplicitList()->end_set(_poSource->getAsImplicitList()->end_get());
365                                 }
366                                 else
367                                 {
368                                         poResult->getAsImplicitList()->end_set(_poSource->getAsImplicitList()->end_get());
369                                 }
370                                 break;
371                         }
372                 default:
373                         break;
374                 }
375                 return poResult;
376         }
377         return NULL;
378 }
379