34c81d9c3b9c4b46a37eb6a9bca1738a4b0090aa
[scilab.git] / scilab / modules / ast / src / cpp / operations / types_multiplication.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
4  *  Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
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 #include "types_multiplication.hxx"
15 #include "types_addition.hxx"
16 #include "arrayof.hxx"
17
18 #include "scilabexception.hxx"
19
20 extern "C"
21 {
22 #include "matrix_multiplication.h"
23 #include "matrix_addition.h"
24 #include "operation_f.h"
25 #include "localization.h"
26 #include "charEncoding.h"
27 #include "elem_common.h"
28 }
29
30 using namespace types;
31
32 InternalType *GenericDotTimes(InternalType *_pLeftOperand, InternalType *_pRightOperand)
33 {
34     InternalType *pResult = NULL;
35
36     if (_pLeftOperand->isDouble() && _pLeftOperand->getAs<Double>()->isEmpty())
37     {
38         return Double::Empty();
39     }
40
41     if (_pRightOperand->isDouble() && _pRightOperand->getAs<Double>()->isEmpty())
42     {
43         return Double::Empty();
44     }
45
46     /*
47     ** DOUBLE .* DOUBLE
48     */
49     if (_pLeftOperand->isDouble() && _pRightOperand->isDouble())
50     {
51         Double *pL   = _pLeftOperand->getAs<Double>();
52         Double *pR   = _pRightOperand->getAs<Double>();
53
54         int iResult = DotMultiplyDoubleByDouble(pL, pR, (Double**)&pResult);
55         if (iResult)
56         {
57             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
58         }
59
60         return pResult;
61     }
62
63     /*
64     ** SPARSE .* SPARSE
65     */
66     if (_pLeftOperand->isSparse() && _pRightOperand->isSparse())
67     {
68         Sparse *pL   = _pLeftOperand->getAs<Sparse>();
69         Sparse *pR   = _pRightOperand->getAs<Sparse>();
70
71         int iResult = DotMultiplySparseBySparse(pL, pR, (Sparse**)&pResult);
72         if (iResult)
73         {
74             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
75         }
76
77         return pResult;
78     }
79
80     /*
81     ** SPARSE .* DOUBLE
82     */
83     if (_pLeftOperand->isSparse() && _pRightOperand->isDouble())
84     {
85         Sparse *pL   = _pLeftOperand->getAs<Sparse>();
86         Double *pR   = _pRightOperand->getAs<Double>();
87
88         int iResult = DotMultiplySparseByDouble(pL, pR, (GenericType**)&pResult);
89         if (iResult)
90         {
91             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
92         }
93
94         return pResult;
95     }
96
97     /*
98     ** DOUBLE .* SPARSE
99     */
100     if (_pLeftOperand->isDouble() && _pRightOperand->isSparse())
101     {
102         Double *pL   = _pLeftOperand->getAs<Double>();
103         Sparse *pR   = _pRightOperand->getAs<Sparse>();
104
105         int iResult = DotMultiplyDoubleBySparse(pL, pR, (GenericType**)&pResult);
106         if (iResult)
107         {
108             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
109         }
110
111         return pResult;
112     }
113
114     /*
115     ** DOUBLE .* POLY
116     */
117     if (_pLeftOperand->isDouble() && _pRightOperand->isPoly())
118     {
119         Double *pL   = _pLeftOperand->getAs<Double>();
120         Polynom *pR  = _pRightOperand->getAs<Polynom>();
121
122         int iResult = DotMultiplyDoubleByPoly(pL, pR, (Polynom**)&pResult);
123         if (iResult)
124         {
125             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
126         }
127
128         return pResult;
129     }
130
131     /*
132     ** POLY .* DOUBLE
133     */
134     if (_pLeftOperand->isPoly() && _pRightOperand->isDouble())
135     {
136         Polynom *pL   = _pLeftOperand->getAs<Polynom>();
137         Double *pR    = _pRightOperand->getAs<Double>();
138
139         int iResult = DotMultiplyPolyByDouble(pL, pR, (Polynom**)&pResult);
140         if (iResult)
141         {
142             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
143         }
144
145         return pResult;
146     }
147
148     /*
149     ** POLY .* POLY
150     */
151     if (_pLeftOperand->isPoly() && _pRightOperand->isPoly())
152     {
153         Polynom *pL   = _pLeftOperand->getAs<Polynom>();
154         Polynom *pR   = _pRightOperand->getAs<Polynom>();
155
156         int iResult = DotMultiplyPolyByPoly(pL, pR, (Polynom**)&pResult);
157         if (iResult)
158         {
159             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
160         }
161
162         return pResult;
163     }
164
165     /*
166     ** Default case : Return NULL will Call Overloading.
167     */
168     return NULL;
169 }
170
171 InternalType *GenericTimes(InternalType *_pLeftOperand, InternalType *_pRightOperand)
172 {
173     InternalType *pResult = NULL;
174     GenericType::ScilabType TypeL = _pLeftOperand->getType();
175     GenericType::ScilabType TypeR = _pRightOperand->getType();
176
177     if (TypeL == GenericType::ScilabDouble && _pLeftOperand->getAs<Double>()->isEmpty())
178     {
179         return Double::Empty();
180     }
181
182     if (TypeR == GenericType::ScilabDouble && _pRightOperand->getAs<Double>()->isEmpty())
183     {
184         return Double::Empty();
185     }
186
187     /*
188     ** DOUBLE * DOUBLE
189     */
190     if (TypeL == GenericType::ScilabDouble && TypeR == GenericType::ScilabDouble)
191     {
192         Double *pL   = _pLeftOperand->getAs<Double>();
193         Double *pR   = _pRightOperand->getAs<Double>();
194
195         int iResult = MultiplyDoubleByDouble(pL, pR, (Double**)&pResult);
196         if (iResult)
197         {
198             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
199         }
200
201         return pResult;
202     }
203
204     /*
205     ** DOUBLE * POLY
206     */
207     else if (TypeL == InternalType::ScilabDouble && TypeR == InternalType::ScilabPolynom)
208     {
209         Double *pL   = _pLeftOperand->getAs<Double>();
210         Polynom *pR     = _pRightOperand->getAs<types::Polynom>();
211
212         int iResult = MultiplyDoubleByPoly(pL, pR, (Polynom**)&pResult);
213         if (iResult)
214         {
215             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
216         }
217
218         return pResult;
219     }
220
221     /*
222     ** POLY * DOUBLE
223     */
224     else if (TypeL == InternalType::ScilabPolynom && TypeR == InternalType::ScilabDouble)
225     {
226         Polynom *pL          = _pLeftOperand->getAs<types::Polynom>();
227         Double *pR              = _pRightOperand->getAs<Double>();
228
229         int iResult = MultiplyPolyByDouble(pL, pR, (Polynom**)&pResult);
230         if (iResult)
231         {
232             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
233         }
234
235         return pResult;
236     }
237
238     /*
239     ** POLY * POLY
240     */
241     else if (TypeL == InternalType::ScilabPolynom && TypeR == InternalType::ScilabPolynom)
242     {
243         Polynom *pL          = _pLeftOperand->getAs<types::Polynom>();
244         Polynom *pR          = _pRightOperand->getAs<types::Polynom>();
245
246         int iResult = MultiplyPolyByPoly(pL, pR, (Polynom**)&pResult);
247         if (iResult)
248         {
249             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
250         }
251
252         return pResult;
253     }
254
255     /*
256     ** SPARSE * SPARSE
257     */
258     if (TypeL == GenericType::ScilabSparse && TypeR == GenericType::ScilabSparse)
259     {
260         Sparse *pL   = _pLeftOperand->getAs<Sparse>();
261         Sparse *pR   = _pRightOperand->getAs<Sparse>();
262
263         int iResult = MultiplySparseBySparse(pL, pR, (Sparse**)&pResult);
264         if (iResult)
265         {
266             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
267         }
268
269         return pResult;
270     }
271
272     /*
273     ** DOUBLE * SPARSE
274     */
275     if (TypeL == GenericType::ScilabDouble && TypeR == GenericType::ScilabSparse)
276     {
277         Double *pL   = _pLeftOperand->getAs<Double>();
278         Sparse *pR   = _pRightOperand->getAs<Sparse>();
279
280         int iResult = MultiplyDoubleBySparse(pL, pR, (GenericType**)&pResult);
281         if (iResult)
282         {
283             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
284         }
285
286         return pResult;
287     }
288
289     /*
290     ** SPARSE * DOUBLE
291     */
292     if (TypeL == GenericType::ScilabSparse && TypeR == GenericType::ScilabDouble)
293     {
294         Sparse *pL   = _pLeftOperand->getAs<Sparse>();
295         Double *pR   = _pRightOperand->getAs<Double>();
296
297         int iResult = MultiplySparseByDouble(pL, pR, (GenericType**)&pResult);
298         if (iResult)
299         {
300             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
301         }
302
303         return pResult;
304     }
305
306     /*
307     ** Default case : Return NULL will Call Overloading.
308     */
309     return NULL;
310
311 }
312
313 int MultiplyDoubleByDouble(Double* _pDouble1, Double* _pDouble2, Double** _pDoubleOut)
314 {
315     if (_pDouble1->isScalar())
316     {
317         bool bComplex1  = _pDouble1->isComplex();
318         bool bComplex2  = _pDouble2->isComplex();
319
320         (*_pDoubleOut) = new Double(_pDouble2->getDims(), _pDouble2->getDimsArray(), bComplex1 | bComplex2);
321
322         if (bComplex1 == false && bComplex2 == false)
323         {
324             iMultiRealScalarByRealMatrix(_pDouble1->get(0), _pDouble2->get(), _pDouble2->getSize(), 1, (*_pDoubleOut)->get());
325         }
326         else if (bComplex1 == false && bComplex2 == true)
327         {
328             iMultiRealScalarByComplexMatrix(_pDouble1->get(0), _pDouble2->get(), _pDouble2->getImg(), _pDouble2->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
329         }
330         else if (bComplex1 == true && bComplex2 == false)
331         {
332             iMultiComplexScalarByRealMatrix(_pDouble1->get(0), _pDouble1->getImg(0), _pDouble2->get(), _pDouble2->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
333         }
334         else //if(bComplex1 == true && bComplex2 == true)
335         {
336             iMultiComplexScalarByComplexMatrix(_pDouble1->get(0), _pDouble1->getImg(0), _pDouble2->get(), _pDouble2->getImg(), _pDouble2->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
337         }
338
339         return 0;
340     }
341
342     if (_pDouble2->isScalar())
343     {
344         bool bComplex1  = _pDouble1->isComplex();
345         bool bComplex2  = _pDouble2->isComplex();
346
347         (*_pDoubleOut) = new Double(_pDouble1->getDims(), _pDouble1->getDimsArray(), bComplex1 | bComplex2);
348
349         if (bComplex1 == false && bComplex2 == false)
350         {
351             //Real Matrix by Real Scalar
352             iMultiRealScalarByRealMatrix(_pDouble2->get(0), _pDouble1->get(), _pDouble1->getSize(), 1, (*_pDoubleOut)->get());
353         }
354         else if (bComplex1 == false && bComplex2 == true)
355         {
356             //Real Matrix by Scalar Complex
357             iMultiComplexScalarByRealMatrix(_pDouble2->get(0), _pDouble2->getImg(0), _pDouble1->get(), _pDouble1->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
358         }
359         else if (bComplex1 == true && bComplex2 == false)
360         {
361             iMultiRealScalarByComplexMatrix(_pDouble2->get(0, 0), _pDouble1->get(), _pDouble1->getImg(), _pDouble1->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
362         }
363         else //if(bComplex1 == true && bComplex2 == true)
364         {
365             iMultiComplexScalarByComplexMatrix(_pDouble2->get(0, 0), _pDouble2->getImg(0, 0), _pDouble1->get(), _pDouble1->getImg(), _pDouble1->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
366         }
367
368         return 0;
369     }
370
371     if (_pDouble1->getDims() > 2 || _pDouble2->getDims() > 2 || _pDouble1->getCols() != _pDouble2->getRows())
372     {
373         return 1;
374     }
375
376     bool bComplex1  = _pDouble1->isComplex();
377     bool bComplex2  = _pDouble2->isComplex();
378     (*_pDoubleOut) = new Double(_pDouble1->getRows(), _pDouble2->getCols(), bComplex1 | bComplex2);
379
380     if (bComplex1 == false && bComplex2 == false)
381     {
382         //Real Matrix by Real Matrix
383         iMultiRealMatrixByRealMatrix(
384             _pDouble1->get(), _pDouble1->getRows(), _pDouble1->getCols(),
385             _pDouble2->get(), _pDouble2->getRows(), _pDouble2->getCols(),
386             (*_pDoubleOut)->get());
387     }
388     else if (bComplex1 == false && bComplex2 == true)
389     {
390         //Real Matrix by Matrix Complex
391         iMultiRealMatrixByComplexMatrix(
392             _pDouble1->get(), _pDouble1->getRows(), _pDouble1->getCols(),
393             _pDouble2->get(), _pDouble2->getImg(), _pDouble2->getRows(), _pDouble2->getCols(),
394             (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
395     }
396     else if (bComplex1 == true && bComplex2 == false)
397     {
398         //Complex Matrix by Real Matrix
399         iMultiComplexMatrixByRealMatrix(
400             _pDouble1->get(), _pDouble1->getImg(), _pDouble1->getRows(), _pDouble1->getCols(),
401             _pDouble2->get(), _pDouble2->getRows(), _pDouble2->getCols(),
402             (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
403     }
404     else //if(bComplex1 == true && bComplex2 == true)
405     {
406         //Complex Matrix by Complex Matrix
407         iMultiComplexMatrixByComplexMatrix(
408             _pDouble1->get(), _pDouble1->getImg(), _pDouble1->getRows(), _pDouble1->getCols(),
409             _pDouble2->get(), _pDouble2->getImg(), _pDouble2->getRows(), _pDouble2->getCols(),
410             (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
411     }
412     return 0;
413 }
414
415 int DotMultiplyDoubleByDouble(Double* _pDouble1, Double* _pDouble2, Double**  _pDoubleOut)
416 {
417     bool bComplex1  = _pDouble1->isComplex();
418     bool bComplex2  = _pDouble2->isComplex();
419     bool bScalar1   = _pDouble1->isScalar();
420     bool bScalar2   = _pDouble2->isScalar();
421
422     if (bScalar1)
423     {
424         (*_pDoubleOut) = new Double(_pDouble2->getDims(), _pDouble2->getDimsArray(), _pDouble1->isComplex() | _pDouble2->isComplex());
425         if (bComplex1 == false && bComplex2 == false)
426         {
427             iMultiRealScalarByRealMatrix(_pDouble1->get(0), _pDouble2->get(), _pDouble2->getSize(), 1, (*_pDoubleOut)->get());
428         }
429         else if (bComplex1 == false && bComplex2 == true)
430         {
431             iMultiRealScalarByComplexMatrix(_pDouble1->get(0), _pDouble2->get(), _pDouble2->getImg(), _pDouble2->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
432         }
433         else if (bComplex1 == true && bComplex2 == false)
434         {
435             iMultiComplexScalarByRealMatrix(_pDouble1->get(0), _pDouble1->getImg(0), _pDouble2->get(), _pDouble2->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
436         }
437         else //if(bComplex1 == true && bComplex2 == true)
438         {
439             iMultiComplexScalarByComplexMatrix(_pDouble1->get(0), _pDouble1->getImg(0), _pDouble2->get(), _pDouble2->getImg(), _pDouble2->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
440         }
441
442         return 0;
443     }
444
445     if (bScalar2)
446     {
447         (*_pDoubleOut) = new Double(_pDouble1->getDims(), _pDouble1->getDimsArray(), _pDouble1->isComplex() | _pDouble2->isComplex());
448         if (bComplex1 == false && bComplex2 == false)
449         {
450             //Real Matrix by Real Scalar
451             iMultiRealScalarByRealMatrix(_pDouble2->get(0), _pDouble1->get(), _pDouble1->getSize(), 1, (*_pDoubleOut)->get());
452         }
453         else if (bComplex1 == false && bComplex2 == true)
454         {
455             //Real Matrix by Scalar Complex
456             iMultiComplexScalarByRealMatrix(_pDouble2->get(0), _pDouble2->getImg(0), _pDouble1->get(), _pDouble1->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
457         }
458         else if (bComplex1 == true && bComplex2 == false)
459         {
460             iMultiRealScalarByComplexMatrix(_pDouble2->get(0), _pDouble1->get(), _pDouble1->getImg(), _pDouble1->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
461         }
462         else //if(bComplex1 == true && bComplex2 == true)
463         {
464             iMultiComplexScalarByComplexMatrix(_pDouble2->get(0), _pDouble2->getImg(0), _pDouble1->get(), _pDouble1->getImg(), _pDouble1->getSize(), 1, (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg());
465         }
466
467         return 0;
468     }
469
470     if (_pDouble1->getDims() != _pDouble2->getDims())
471     {
472         return 1;
473     }
474
475     int* piDims1 = _pDouble1->getDimsArray();
476     int* piDims2 = _pDouble2->getDimsArray();
477
478     for (int i = 0 ; i < _pDouble1->getDims() ; i++)
479     {
480         if (piDims1[i] != piDims2[i])
481         {
482             return 0;
483         }
484     }
485
486     (*_pDoubleOut) = new Double(_pDouble1->getDims(), _pDouble1->getDimsArray(), _pDouble1->isComplex() | _pDouble2->isComplex());
487     if (bComplex1 == false && bComplex2 == false)
488     {
489         iDotMultiplyRealMatrixByRealMatrix(_pDouble1->get(), _pDouble2->get(), (*_pDoubleOut)->get(), _pDouble1->getSize(), 1);
490     }
491     else if (bComplex1 == false && bComplex2 == true)
492     {
493         iDotMultiplyRealMatrixByComplexMatrix(_pDouble1->get(), _pDouble2->get(), _pDouble2->getImg(), (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg(), _pDouble1->getSize(), 1);
494     }
495     else if (bComplex1 == true && bComplex2 == false)
496     {
497         iDotMultiplyComplexMatrixByRealMatrix(_pDouble1->get(), _pDouble1->getImg(), _pDouble2->get(), (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg(), _pDouble1->getSize(), 1);
498     }
499     else //if(bComplex1 == true && bComplex2 == true)
500     {
501         iDotMultiplyComplexMatrixByComplexMatrix(_pDouble1->get(), _pDouble1->getImg(), _pDouble2->get(), _pDouble2->getImg(), (*_pDoubleOut)->get(), (*_pDoubleOut)->getImg(), _pDouble1->getSize(), 1);
502     }
503
504     return 0;
505 }
506 int MultiplyDoubleByPoly(Double* _pDouble, Polynom* _pPoly, Polynom** _pPolyOut)
507 {
508     bool bComplex1  = _pDouble->isComplex();
509     bool bComplex2  = _pPoly->isComplex();
510     bool bScalar1   = _pDouble->isScalar();
511     bool bScalar2   = _pPoly->isScalar();
512
513     if (_pDouble->isScalar())
514     {
515         int* piRank = new int[_pPoly->getSize()];
516         for (int i = 0 ; i < _pPoly->getSize() ; i++)
517         {
518             piRank[i] = _pPoly->get(i)->getRank();
519         }
520
521         (*_pPolyOut) = new Polynom(_pPoly->getVariableName(), _pPoly->getDims(), _pPoly->getDimsArray(), piRank);
522         delete[] piRank;
523         if (bComplex1 || bComplex2)
524         {
525             (*_pPolyOut)->setComplex(true);
526         }
527
528         for (int i = 0 ; i < _pPoly->getSize() ; i++)
529         {
530             SinglePoly *pPolyIn     = _pPoly->get(i);
531             double* pRealIn         = pPolyIn->getCoef()->get();
532             double* pImgIn          = pPolyIn->getCoef()->getImg();
533
534             SinglePoly *pPolyOut    = (*_pPolyOut)->get(i);
535             double* pRealOut        = pPolyOut->getCoef()->get();
536             double* pImgOut         = pPolyOut->getCoef()->getImg();
537
538             if (bComplex1 == false && bComplex2 == false)
539             {
540                 iMultiRealScalarByRealMatrix(_pDouble->get(0), pRealIn, 1, pPolyIn->getRank(), pRealOut);
541             }
542             else if (bComplex1 == false && bComplex2 == true)
543             {
544                 iMultiRealScalarByComplexMatrix(_pDouble->get(0), pRealIn, pImgIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
545             }
546             else if (bComplex1 == true && bComplex2 == false)
547             {
548                 iMultiComplexScalarByRealMatrix(_pDouble->get(0), _pDouble->getImg(0), pRealIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
549             }
550             else if (bComplex1 == true && bComplex2 == true)
551             {
552                 iMultiComplexScalarByComplexMatrix(_pDouble->get(0), _pDouble->getImg(0), pRealIn, pImgIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
553             }
554         }
555         (*_pPolyOut)->updateRank();
556         return 0;
557     }
558
559     if (_pPoly->isScalar())
560     {
561         int* piRank = new int[_pDouble->getSize()];
562         for (int i = 0 ; i < _pDouble->getSize() ; i++)
563         {
564             piRank[i] = _pPoly->get(0)->getRank();
565         }
566
567         (*_pPolyOut) = new Polynom(_pPoly->getVariableName(), _pDouble->getDims(), _pDouble->getDimsArray(), piRank);
568         delete[] piRank;
569         if (bComplex1 || bComplex2)
570         {
571             (*_pPolyOut)->setComplex(true);
572         }
573
574         double *pDoubleR    = _pDouble->get();
575         double *pDoubleI    = _pDouble->getImg();
576
577         SinglePoly *pPolyIn = _pPoly->get(0);
578         double* pRealIn     = pPolyIn->getCoef()->get();
579         double* pImgIn      = pPolyIn->getCoef()->getImg();
580
581         for (int i = 0 ; i < _pDouble->getSize() ; i++)
582         {
583             SinglePoly *pPolyOut    = (*_pPolyOut)->get(i);
584             double* pRealOut        = pPolyOut->getCoef()->get();
585             double* pImgOut         = pPolyOut->getCoef()->getImg();
586
587             if (bComplex1 == false && bComplex2 == false)
588             {
589                 iMultiRealScalarByRealMatrix(pDoubleR[i], pRealIn, 1, pPolyIn->getRank(), pRealOut);
590             }
591             else if (bComplex1 == false && bComplex2 == true)
592             {
593                 iMultiRealScalarByComplexMatrix(pDoubleR[i], pRealIn, pImgIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
594             }
595             else if (bComplex1 == true && bComplex2 == false)
596             {
597                 iMultiComplexScalarByRealMatrix(pDoubleR[i], pDoubleI[i], pRealIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
598             }
599             else if (bComplex1 == true && bComplex2 == true)
600             {
601                 iMultiComplexScalarByComplexMatrix(pDoubleR[i], pDoubleI[i], pRealIn, pImgIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
602             }
603         }
604
605         (*_pPolyOut)->updateRank();
606         return 0;
607     }
608
609     if (_pPoly->getDims() > 2 || _pDouble->getDims() > 2 || _pDouble->getCols() != _pPoly->getRows())
610     {
611         return 1;
612     }
613
614     int* piRank = new int[_pDouble->getRows() * _pPoly->getCols()];
615     for (int i = 0 ; i < _pDouble->getRows() * _pPoly->getCols() ; i++)
616     {
617         piRank[i] = _pPoly->getMaxRank();
618     }
619
620     (*_pPolyOut) = new Polynom(_pPoly->getVariableName(), _pDouble->getRows(), _pPoly->getCols(), piRank);
621     delete[] piRank;
622     if (bComplex1 || bComplex2)
623     {
624         (*_pPolyOut)->setComplex(true);
625     }
626
627     Double *pCoef = _pPoly->getCoef();
628     Double *pTemp = new Double(_pDouble->getRows(), pCoef->getCols(), bComplex1 || bComplex2);
629
630     if (bComplex1 == false && bComplex2 == false)
631     {
632         iMultiRealMatrixByRealMatrix(_pDouble->get(), _pDouble->getRows(), _pDouble->getCols(),
633                                      pCoef->get(), pCoef->getRows(), pCoef->getCols(),
634                                      pTemp->get());
635     }
636     else if (bComplex1 == false && bComplex2 == true)
637     {
638         iMultiRealMatrixByComplexMatrix(_pDouble->get(), _pDouble->getRows(), _pDouble->getCols(),
639                                         pCoef->get(), pCoef->getImg(), pCoef->getRows(), pCoef->getCols(),
640                                         pTemp->get(), pTemp->getImg());
641
642     }
643     else if (bComplex1 == true && bComplex2 == false)
644     {
645         iMultiComplexMatrixByRealMatrix(_pDouble->get(), _pDouble->getImg(), _pDouble->getRows(), _pDouble->getCols(),
646                                         pCoef->get(), pCoef->getRows(), pCoef->getCols(),
647                                         pTemp->get(), pTemp->getImg());
648     }
649     else //if(bComplex1 == true && bComplex2 == true)
650     {
651         iMultiComplexMatrixByComplexMatrix(_pDouble->get(), _pDouble->getImg(), _pDouble->getRows(), _pDouble->getCols(),
652                                            pCoef->get(), pCoef->getImg(), pCoef->getRows(), pCoef->getCols(),
653                                            pTemp->get(), pTemp->getImg());
654     }
655
656     (*_pPolyOut)->setCoef(pTemp);
657     (*_pPolyOut)->updateRank();
658     delete pTemp;
659     return 0;
660 }
661
662 int MultiplyPolyByDouble(Polynom* _pPoly, Double* _pDouble, Polynom **_pPolyOut)
663 {
664     bool bComplex1  = _pPoly->isComplex();
665     bool bComplex2  = _pDouble->isComplex();
666     bool bScalar1   = _pPoly->isScalar();
667     bool bScalar2   = _pDouble->isScalar();
668
669     if (bScalar1)
670     {
671         int* piRank = new int[_pDouble->getSize()];
672         for (int i = 0 ; i < _pDouble->getSize() ; i++)
673         {
674             piRank[i] = _pPoly->get(0)->getRank();
675         }
676
677         (*_pPolyOut) = new Polynom(_pPoly->getVariableName(), _pDouble->getDims(), _pDouble->getDimsArray(), piRank);
678         delete[] piRank;
679         if (bComplex1 || bComplex2)
680         {
681             (*_pPolyOut)->setComplex(true);
682         }
683
684         double *pDoubleR    = _pDouble->get();
685         double *pDoubleI    = _pDouble->getImg();
686
687         SinglePoly *pPolyIn = _pPoly->get(0);
688         double* pRealIn     = pPolyIn->getCoef()->get();
689         double* pImgIn      = pPolyIn->getCoef()->getImg();
690
691         for (int i = 0 ; i < _pDouble->getSize() ; i++)
692         {
693             SinglePoly *pPolyOut    = (*_pPolyOut)->get(i);
694             double* pRealOut        = pPolyOut->getCoef()->get();
695             double* pImgOut         = pPolyOut->getCoef()->getImg();
696
697             if (bComplex1 == false && bComplex2 == false)
698             {
699                 iMultiRealScalarByRealMatrix(pDoubleR[i], pRealIn, 1, pPolyIn->getRank(), pRealOut);
700             }
701             else if (bComplex1 == false && bComplex2 == true)
702             {
703                 iMultiComplexScalarByRealMatrix(pDoubleR[i], pDoubleI[i], pRealIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
704             }
705             else if (bComplex1 == true && bComplex2 == false)
706             {
707                 iMultiRealScalarByComplexMatrix(pDoubleR[i], pRealIn, pImgIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
708             }
709             else if (bComplex1 == true && bComplex2 == true)
710             {
711                 iMultiComplexScalarByComplexMatrix(pDoubleR[i], pDoubleI[i], pRealIn, pImgIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
712             }
713         }
714
715         (*_pPolyOut)->updateRank();
716         return 0;
717     }
718     else if (bScalar2)
719     {
720         int* piRank = new int[_pPoly->getSize()];
721         for (int i = 0 ; i < _pPoly->getSize() ; i++)
722         {
723             piRank[i] = _pPoly->get(i)->getRank();
724         }
725
726         (*_pPolyOut) = new Polynom(_pPoly->getVariableName(), _pPoly->getDims(), _pPoly->getDimsArray(), piRank);
727         delete[] piRank;
728         if (bComplex1 || bComplex2)
729         {
730             (*_pPolyOut)->setComplex(true);
731         }
732
733         for (int i = 0 ; i < _pPoly->getSize() ; i++)
734         {
735             SinglePoly *pPolyIn = _pPoly->get(i);
736             double* pRealIn     = pPolyIn->getCoef()->get();
737             double* pImgIn      = pPolyIn->getCoef()->getImg();
738
739             SinglePoly *pPolyOut    = (*_pPolyOut)->get(i);
740             double* pRealOut        = pPolyOut->getCoef()->get();
741             double* pImgOut         = pPolyOut->getCoef()->getImg();
742
743             if (bComplex1 == false && bComplex2 == false)
744             {
745                 iMultiRealScalarByRealMatrix(_pDouble->get(0), pRealIn, 1, pPolyIn->getRank(), pRealOut);
746             }
747             else if (bComplex1 == false && bComplex2 == true)
748             {
749                 iMultiComplexScalarByRealMatrix(_pDouble->get(0), _pDouble->getImg(0), pRealIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
750             }
751             else if (bComplex1 == true && bComplex2 == false)
752             {
753                 iMultiRealScalarByComplexMatrix(_pDouble->get(0), pRealIn, pImgIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
754             }
755             else if (bComplex1 == true && bComplex2 == true)
756             {
757                 iMultiComplexScalarByComplexMatrix(_pDouble->get(0), _pDouble->getImg(0), pRealIn, pImgIn, 1, pPolyIn->getRank(), pRealOut, pImgOut);
758             }
759         }
760
761         (*_pPolyOut)->updateRank();
762         return 0;
763     }
764
765     if (_pDouble->getDims() > 2 || _pPoly->getDims() > 2 || _pPoly->getCols() != _pDouble->getRows())
766     {
767         return 1;
768     }
769
770     int* piRank = new int[_pPoly->getRows() * _pDouble->getCols()];
771     for (int i = 0 ; i < _pPoly->getRows() * _pDouble->getCols() ; i++)
772     {
773         piRank[i] = _pPoly->getMaxRank();
774     }
775
776     (*_pPolyOut) = new Polynom(_pPoly->getVariableName(), _pPoly->getRows(), _pDouble->getCols(), piRank);
777     delete[] piRank;
778     if (bComplex1 || bComplex2)
779     {
780         (*_pPolyOut)->setComplex(true);
781     }
782
783
784     //Distribution a la mano par appels a des sous-fonctions ( iMulti...ScalarBy...Scalar ) plus iAdd...To... )
785
786     //for each line of _pPoly
787     for (int iRow1 = 0 ; iRow1 < _pPoly->getRows() ; iRow1++)
788     {
789         //for each col of _pDouble
790         for (int iCol2 = 0 ; iCol2 < _pDouble->getCols() ; iCol2++)
791         {
792             //for each rows of _pDouble / cols of _pPoly
793             for (int iRow2 = 0 ; iRow2 < _pDouble->getRows() ; iRow2++)
794             {
795                 Double *pPolyCoef = _pPoly->get(iRow1, iRow2)->getCoef();
796
797                 Double *pDouble = NULL;
798                 if (bComplex2 == false)
799                 {
800                     pDouble = new Double(_pDouble->get(iRow2, iCol2));
801                 }
802                 else
803                 {
804                     pDouble = new Double(_pDouble->get(iRow2, iCol2), _pDouble->getImg(iRow2, iCol2));
805                 }
806
807                 Double *TimeDouble = NULL; //(pPolyCoef->getRows(), pPolyCoef->getCols(), bComplexOut);
808                 MultiplyDoubleByDouble(pPolyCoef, pDouble, &TimeDouble);
809
810                 //Adjust size to allow vector multiplication
811                 Double* pCoef = (*_pPolyOut)->get(iRow1, iCol2)->getCoef();
812
813                 if (TimeDouble->getRows() > pCoef->getRows())
814                 {
815                     pCoef->resize(TimeDouble->getRows(), pCoef->getCols());
816                 }
817                 else if (TimeDouble->getRows() < pCoef->getRows())
818                 {
819                     TimeDouble->resize(pCoef->getRows(), TimeDouble->getCols());
820                 }
821
822                 if (TimeDouble->getCols() > pCoef->getCols())
823                 {
824                     pCoef->resize(pCoef->getRows(), TimeDouble->getCols());
825                 }
826                 else if (TimeDouble->getCols() < pCoef->getCols())
827                 {
828                     TimeDouble->resize(TimeDouble->getRows(), pCoef->getCols());
829                 }
830
831                 add_function pAdd = getAddFunction(TimeDouble->getId(), pCoef->getId());
832                 Double *pAddDouble = (Double*)pAdd(TimeDouble, pCoef);
833                 (*_pPolyOut)->setCoef(iRow1, iCol2, pAddDouble);
834
835                 delete pAddDouble;
836                 delete pDouble;
837             }//for(int iRow2 = 0 ; iRow2 < _pDouble->getRows() ; iRow2++)
838         }//for(int iCol2 = 0 ; iCol2 < _pDouble->getCols() ; iCol2++)
839     }//for(int iRow1 = 0 ; iRow1 < _pPoly->getRows() ; iRow1++)
840
841     (*_pPolyOut)->updateRank();
842     return 0;
843 }
844
845 int MultiplyPolyByPoly(Polynom* _pPoly1, Polynom* _pPoly2, Polynom** _pPolyOut)
846 {
847     bool bComplex1  = _pPoly1->isComplex();
848     bool bComplex2  = _pPoly2->isComplex();
849
850     if (_pPoly1->isScalar() && _pPoly2->isScalar())
851     {
852         //poly1(0) * poly2(0)
853         int* piRank = new int[1];
854         piRank[0] = _pPoly1->get(0)->getRealRank() + _pPoly2->get(0)->getRealRank() + 1;
855
856         (*_pPolyOut) = new Polynom(_pPoly1->getVariableName(), 1, 1, piRank);
857         if (bComplex1 || bComplex2)
858         {
859             (*_pPolyOut)->setComplex(true);
860         }
861         delete[] piRank;
862
863         if (bComplex1 == false && bComplex2 == false)
864         {
865             SinglePoly *pPoly1  = _pPoly1->get(0);
866             SinglePoly *pPoly2  = _pPoly2->get(0);
867             SinglePoly *pPolyOut = (*_pPolyOut)->get(0);
868
869             pPolyOut->getCoef()->setZeros();
870
871             iMultiScilabPolynomByScilabPolynom(
872                 pPoly1->getCoef()->get(), pPoly1->getRank(),
873                 pPoly2->getCoef()->get(), pPoly2->getRank(),
874                 pPolyOut->getCoef()->get(), pPolyOut->getRank());
875         }
876         else if (bComplex1 == false && bComplex2 == true)
877         {
878             SinglePoly *pPoly1  = _pPoly1->get(0);
879             SinglePoly *pPoly2  = _pPoly2->get(0);
880             SinglePoly *pPolyOut = (*_pPolyOut)->get(0);
881
882             pPolyOut->getCoef()->setZeros();
883
884             iMultiScilabPolynomByComplexPoly(
885                 pPoly1->getCoef()->get(), pPoly1->getRank(),
886                 pPoly2->getCoef()->get(), pPoly2->getCoef()->getImg(), pPoly2->getRank(),
887                 pPolyOut->getCoef()->get(), pPolyOut->getCoef()->getImg(), pPolyOut->getRank());
888         }
889         else if (bComplex1 == true && bComplex2 == false)
890         {
891             SinglePoly *pPoly1  = _pPoly1->get(0);
892             SinglePoly *pPoly2  = _pPoly2->get(0);
893             SinglePoly *pPolyOut = (*_pPolyOut)->get(0);
894
895             pPolyOut->getCoef()->setZeros();
896
897             iMultiComplexPolyByScilabPolynom(
898                 pPoly1->getCoef()->get(), pPoly1->getCoef()->getImg(), pPoly1->getRank(),
899                 pPoly2->getCoef()->get(), pPoly2->getRank(),
900                 pPolyOut->getCoef()->get(), pPolyOut->getCoef()->getImg(), pPolyOut->getRank());
901         }
902         else if (bComplex1 == true && bComplex2 == true)
903         {
904             SinglePoly *pPoly1   = _pPoly1->get(0);
905             SinglePoly *pPoly2   = _pPoly2->get(0);
906             SinglePoly *pPolyOut  = (*_pPolyOut)->get(0);
907             Double *pCoef1  = pPoly1->getCoef();
908             Double *pCoef2  = pPoly2->getCoef();
909             Double *pCoefOut = pPolyOut->getCoef();
910
911             pCoefOut->setZeros();
912
913             iMultiComplexPolyByComplexPoly(
914                 pCoef1->get(), pCoef1->getImg(), pPoly1->getRank(),
915                 pCoef2->get(), pCoef2->getImg(), pPoly2->getRank(),
916                 pCoefOut->get(), pCoefOut->getImg(), pPolyOut->getRank());
917         }
918
919         (*_pPolyOut)->updateRank();
920         return 0;
921     }
922
923     if (_pPoly1->isScalar())
924     {
925         //poly1(0) * poly2(n)
926         int* piRank = new int[_pPoly2->getSize()];
927         for (int i = 0 ; i < _pPoly2->getSize() ; i++)
928         {
929             piRank[i] = _pPoly1->get(0)->getRealRank() + _pPoly2->get(i)->getRealRank() + 1;
930         }
931
932         (*_pPolyOut) = new Polynom(_pPoly1->getVariableName(), _pPoly2->getDims(), _pPoly2->getDimsArray(), piRank);
933         if (bComplex1 || bComplex2)
934         {
935             (*_pPolyOut)->setComplex(true);
936         }
937         delete[] piRank;
938
939
940         SinglePoly *pPoly1  = _pPoly1->get(0);
941         if (bComplex1 == false && bComplex2 == false)
942         {
943             for (int iPoly = 0 ; iPoly < _pPoly2->getSize() ; iPoly++)
944             {
945                 SinglePoly *pPoly2  = _pPoly2->get(iPoly);
946                 SinglePoly *pPolyOut = (*_pPolyOut)->get(iPoly);
947
948                 pPolyOut->getCoef()->setZeros();
949
950                 iMultiScilabPolynomByScilabPolynom(
951                     pPoly1->getCoef()->get(), pPoly1->getRank(),
952                     pPoly2->getCoef()->get(), pPoly2->getRank(),
953                     pPolyOut->getCoef()->get(), pPolyOut->getRank());
954             }
955         }
956         else if (bComplex1 == false && bComplex2 == true)
957         {
958             for (int iPoly = 0 ; iPoly < _pPoly2->getSize() ; iPoly++)
959             {
960                 SinglePoly *pPoly2  = _pPoly2->get(iPoly);
961                 SinglePoly *pPolyOut = (*_pPolyOut)->get(iPoly);
962
963                 pPolyOut->getCoef()->setZeros();
964
965                 iMultiScilabPolynomByComplexPoly(
966                     pPoly1->getCoef()->get(), pPoly1->getRank(),
967                     pPoly2->getCoef()->get(), pPoly2->getCoef()->getImg(), pPoly2->getRank(),
968                     pPolyOut->getCoef()->get(), pPolyOut->getCoef()->getImg(), pPolyOut->getRank());
969             }
970         }
971         else if (bComplex1 == true && bComplex2 == false)
972         {
973             for (int iPoly = 0 ; iPoly < _pPoly2->getSize() ; iPoly++)
974             {
975                 SinglePoly *pPoly2  = _pPoly2->get(iPoly);
976                 SinglePoly *pPolyOut = (*_pPolyOut)->get(iPoly);
977
978                 pPolyOut->getCoef()->setZeros();
979
980                 iMultiComplexPolyByScilabPolynom(
981                     pPoly1->getCoef()->get(), pPoly1->getCoef()->getImg(), pPoly1->getRank(),
982                     pPoly2->getCoef()->get(), pPoly2->getRank(),
983                     pPolyOut->getCoef()->get(), pPolyOut->getCoef()->getImg(), pPolyOut->getRank());
984             }
985         }
986         else if (bComplex1 == true && bComplex2 == true)
987         {
988             Double *pCoef1  = pPoly1->getCoef();
989             for (int iPoly = 0 ; iPoly < _pPoly2->getSize() ; iPoly++)
990             {
991                 SinglePoly *pPoly2   = _pPoly2->get(iPoly);
992                 SinglePoly *pPolyOut  = (*_pPolyOut)->get(iPoly);
993                 Double *pCoef2  = pPoly2->getCoef();
994                 Double *pCoefOut = pPolyOut->getCoef();
995
996                 pCoefOut->setZeros();
997
998                 iMultiComplexPolyByComplexPoly(
999                     pCoef1->get(), pCoef1->getImg(), pPoly1->getRank(),
1000                     pCoef2->get(), pCoef2->getImg(), pPoly2->getRank(),
1001                     pCoefOut->get(), pCoefOut->getImg(), pPolyOut->getRank());
1002             }
1003         }
1004
1005         (*_pPolyOut)->updateRank();
1006         return 0;
1007     }
1008
1009     if (_pPoly2->isScalar())
1010     {
1011         //poly1(n) * poly2(0)
1012         int* piRank = new int[_pPoly1->getSize()];
1013         for (int i = 0 ; i < _pPoly1->getSize() ; i++)
1014         {
1015             piRank[i] = _pPoly2->get(0)->getRealRank() + _pPoly1->get(i)->getRealRank() + 1;
1016         }
1017
1018         (*_pPolyOut) = new Polynom(_pPoly1->getVariableName(), _pPoly1->getDims(), _pPoly1->getDimsArray(), piRank);
1019         if (bComplex1 || bComplex2)
1020         {
1021             (*_pPolyOut)->setComplex(true);
1022         }
1023         delete[] piRank;
1024
1025         SinglePoly *pPoly2  = _pPoly2->get(0);
1026         if (bComplex1 == false && bComplex2 == false)
1027         {
1028             for (int iPoly = 0 ; iPoly < _pPoly1->getSize() ; iPoly++)
1029             {
1030                 SinglePoly *pPoly1  = _pPoly1->get(iPoly);
1031                 SinglePoly *pPolyOut = (*_pPolyOut)->get(iPoly);
1032
1033                 pPolyOut->getCoef()->setZeros();
1034
1035                 iMultiScilabPolynomByScilabPolynom(
1036                     pPoly1->getCoef()->get(), pPoly1->getRank(),
1037                     pPoly2->getCoef()->get(), pPoly2->getRank(),
1038                     pPolyOut->getCoef()->get(), pPolyOut->getRank());
1039             }
1040         }
1041         else if (bComplex1 == false && bComplex2 == true)
1042         {
1043             for (int iPoly = 0 ; iPoly < _pPoly1->getSize() ; iPoly++)
1044             {
1045                 SinglePoly *pPoly1  = _pPoly1->get(iPoly);
1046                 SinglePoly *pPolyOut = (*_pPolyOut)->get(iPoly);
1047
1048                 pPolyOut->getCoef()->setZeros();
1049
1050                 iMultiScilabPolynomByComplexPoly(
1051                     pPoly1->getCoef()->get(), pPoly1->getRank(),
1052                     pPoly2->getCoef()->get(), pPoly2->getCoef()->getImg(), pPoly2->getRank(),
1053                     pPolyOut->getCoef()->get(), pPolyOut->getCoef()->getImg(), pPolyOut->getRank());
1054             }
1055         }
1056         else if (bComplex1 == true && bComplex2 == false)
1057         {
1058             for (int iPoly = 0 ; iPoly < _pPoly1->getSize() ; iPoly++)
1059             {
1060                 SinglePoly *pPoly1  = _pPoly1->get(iPoly);
1061                 SinglePoly *pPolyOut = (*_pPolyOut)->get(iPoly);
1062
1063                 pPolyOut->getCoef()->setZeros();
1064
1065                 iMultiComplexPolyByScilabPolynom(
1066                     pPoly1->getCoef()->get(), pPoly1->getCoef()->getImg(), pPoly1->getRank(),
1067                     pPoly2->getCoef()->get(), pPoly2->getRank(),
1068                     pPolyOut->getCoef()->get(), pPolyOut->getCoef()->getImg(), pPolyOut->getRank());
1069             }
1070         }
1071         else if (bComplex1 == true && bComplex2 == true)
1072         {
1073             Double *pCoef2  = pPoly2->getCoef();
1074             for (int iPoly = 0 ; iPoly < _pPoly1->getSize() ; iPoly++)
1075             {
1076                 SinglePoly *pPoly1   = _pPoly1->get(iPoly);
1077                 SinglePoly *pPolyOut  = (*_pPolyOut)->get(iPoly);
1078                 Double *pCoef1  = pPoly1->getCoef();
1079                 Double *pCoefOut = pPolyOut->getCoef();
1080
1081                 pCoefOut->setZeros();
1082
1083                 iMultiComplexPolyByComplexPoly(
1084                     pCoef1->get(), pCoef1->getImg(), pPoly1->getRank(),
1085                     pCoef2->get(), pCoef2->getImg(), pPoly2->getRank(),
1086                     pCoefOut->get(), pCoefOut->getImg(), pPolyOut->getRank());
1087             }
1088         }
1089
1090         (*_pPolyOut)->updateRank();
1091         return 0;
1092     }
1093
1094     if (_pPoly1->getDims() > 2 || _pPoly2->getDims() > 2 || _pPoly1->getCols() != _pPoly2->getRows())
1095     {
1096         return 1;
1097     }
1098
1099     // matrix by matrix
1100     int* piRank = new int[_pPoly1->getRows() * _pPoly2->getCols()];
1101     for (int i = 0 ; i < _pPoly1->getRows() * _pPoly2->getCols() ; i++)
1102     {
1103         piRank[i] = _pPoly1->getMaxRank() + _pPoly2->getMaxRank() - 1;
1104     }
1105
1106     (*_pPolyOut) = new Polynom(_pPoly1->getVariableName(), _pPoly1->getRows(), _pPoly2->getCols(), piRank);
1107     if (bComplex1 || bComplex2)
1108     {
1109         (*_pPolyOut)->setComplex(true);
1110     }
1111
1112     delete[] piRank;
1113
1114
1115     if (bComplex1 == false && bComplex2 == false)
1116     {
1117         double *pReal = NULL;
1118         SinglePoly *pTemp  = new SinglePoly(&pReal, (*_pPolyOut)->getMaxRank());
1119
1120         for (int iRow = 0 ; iRow < _pPoly1->getRows() ; iRow++)
1121         {
1122             for (int iCol = 0 ; iCol < _pPoly2->getCols() ; iCol++)
1123             {
1124                 SinglePoly *pResult = (*_pPolyOut)->get(iRow, iCol);
1125                 pResult->getCoef()->setZeros();
1126
1127                 for (int iCommon = 0 ; iCommon < _pPoly1->getCols() ; iCommon++)
1128                 {
1129                     SinglePoly *pL   = _pPoly1->get(iRow, iCommon);
1130                     SinglePoly *pR   = _pPoly2->get(iCommon, iCol);
1131
1132                     pTemp->getCoef()->setZeros();
1133
1134                     iMultiScilabPolynomByScilabPolynom(
1135                         pL->getCoef()->get(), pL->getRank(),
1136                         pR->getCoef()->get(), pR->getRank(),
1137                         pTemp->getCoef()->get(), pL->getRank() + pR->getRank() - 1);
1138
1139                     iAddScilabPolynomToScilabPolynom(
1140                         pResult->getCoef()->get(), pResult->getRank(),
1141                         pTemp->getCoef()->get(), pResult->getRank(),
1142                         pResult->getCoef()->get(), pResult->getRank());
1143                 }
1144             }
1145         }
1146     }
1147     else if (bComplex1 == false && bComplex2 == true)
1148     {
1149         double *pReal = NULL;
1150         double *pImg = NULL;
1151         SinglePoly *pTemp  = new SinglePoly(&pReal, &pImg, (*_pPolyOut)->getMaxRank());
1152
1153         for (int iRow = 0 ; iRow < _pPoly1->getRows() ; iRow++)
1154         {
1155             for (int iCol = 0 ; iCol < _pPoly2->getCols() ; iCol++)
1156             {
1157                 SinglePoly *pResult = (*_pPolyOut)->get(iRow, iCol);
1158                 pResult->getCoef()->setZeros();
1159
1160                 for (int iCommon = 0 ; iCommon < _pPoly1->getCols() ; iCommon++)
1161                 {
1162                     SinglePoly *pL   = _pPoly1->get(iRow, iCommon);
1163                     SinglePoly *pR   = _pPoly2->get(iCommon, iCol);
1164
1165                     pTemp->getCoef()->setZeros();
1166
1167                     iMultiScilabPolynomByComplexPoly(
1168                         pL->getCoef()->get(), pL->getRank(),
1169                         pR->getCoef()->get(), pR->getCoef()->getImg(), pR->getRank(),
1170                         pTemp->getCoef()->get(), pTemp->getCoef()->getImg(), pL->getRank() + pR->getRank() - 1);
1171
1172                     iAddComplexPolyToComplexPoly(
1173                         pResult->getCoef()->get(), pResult->getCoef()->getImg(), pResult->getRank(),
1174                         pTemp->getCoef()->get(), pTemp->getCoef()->getImg(), pResult->getRank(),
1175                         pResult->getCoef()->get(), pResult->getCoef()->getImg(), pResult->getRank());
1176                 }
1177             }
1178         }
1179     }
1180     else if (bComplex1 == true && bComplex2 == false)
1181     {
1182         double *pReal = NULL;
1183         double *pImg = NULL;
1184         SinglePoly *pTemp  = new SinglePoly(&pReal, &pImg, (*_pPolyOut)->getMaxRank());
1185
1186         for (int iRow = 0 ; iRow < _pPoly1->getRows() ; iRow++)
1187         {
1188             for (int iCol = 0 ; iCol < _pPoly2->getCols() ; iCol++)
1189             {
1190                 SinglePoly *pResult = (*_pPolyOut)->get(iRow, iCol);
1191                 pResult->getCoef()->setZeros();
1192
1193                 for (int iCommon = 0 ; iCommon < _pPoly1->getCols() ; iCommon++)
1194                 {
1195                     SinglePoly *pL   = _pPoly1->get(iRow, iCommon);
1196                     SinglePoly *pR   = _pPoly2->get(iCommon, iCol);
1197
1198                     pTemp->getCoef()->setZeros();
1199
1200                     iMultiScilabPolynomByComplexPoly(
1201                         pR->getCoef()->get(), pR->getRank(),
1202                         pL->getCoef()->get(), pL->getCoef()->getImg(), pL->getRank(),
1203                         pTemp->getCoef()->get(), pTemp->getCoef()->getImg(), pL->getRank() + pR->getRank() - 1);
1204
1205                     iAddComplexPolyToComplexPoly(
1206                         pResult->getCoef()->get(), pResult->getCoef()->getImg(), pResult->getRank(),
1207                         pTemp->getCoef()->get(), pTemp->getCoef()->getImg(), pResult->getRank(),
1208                         pResult->getCoef()->get(), pResult->getCoef()->getImg(), pResult->getRank());
1209                 }
1210             }
1211         }
1212     }
1213     else if (bComplex1 == true && bComplex2 == true)
1214     {
1215         double *pReal = NULL;
1216         double *pImg = NULL;
1217         SinglePoly *pTemp  = new SinglePoly(&pReal, &pImg, (*_pPolyOut)->getMaxRank());
1218
1219         for (int iRow = 0 ; iRow < _pPoly1->getRows() ; iRow++)
1220         {
1221             for (int iCol = 0 ; iCol < _pPoly2->getCols() ; iCol++)
1222             {
1223                 SinglePoly *pResult = (*_pPolyOut)->get(iRow, iCol);
1224                 pResult->getCoef()->setZeros();
1225
1226                 for (int iCommon = 0 ; iCommon < _pPoly1->getCols() ; iCommon++)
1227                 {
1228                     SinglePoly *pL   = _pPoly1->get(iRow, iCommon);
1229                     SinglePoly *pR   = _pPoly2->get(iCommon, iCol);
1230
1231                     pTemp->getCoef()->setZeros();
1232
1233                     iMultiComplexPolyByComplexPoly(
1234                         pL->getCoef()->get(), pL->getCoef()->getImg(), pL->getRank(),
1235                         pR->getCoef()->get(), pR->getCoef()->getImg(), pR->getRank(),
1236                         pTemp->getCoef()->get(), pTemp->getCoef()->getImg(), pL->getRank() + pR->getRank() - 1);
1237
1238                     iAddComplexPolyToComplexPoly(
1239                         pResult->getCoef()->get(), pResult->getCoef()->getImg(), pResult->getRank(),
1240                         pTemp->getCoef()->get(), pTemp->getCoef()->getImg(), pResult->getRank(),
1241                         pResult->getCoef()->get(), pResult->getCoef()->getImg(), pResult->getRank());
1242                 }
1243             }
1244         }
1245     }
1246     (*_pPolyOut)->updateRank();
1247
1248     return 0;
1249 }
1250
1251 int MultiplySparseBySparse(Sparse* _pSparse1, Sparse* _pSparse2, Sparse** _pSparseOut)
1252 {
1253     if (_pSparse1->isScalar())
1254     {
1255         //scalar * sp
1256         Double* pDbl = NULL;
1257         if (_pSparse1->isComplex())
1258         {
1259             std::complex<double> dbl = _pSparse1->getImg(0, 0);
1260             pDbl = new Double(dbl.real(), dbl.imag());
1261         }
1262         else
1263         {
1264             pDbl = new Double(_pSparse1->get(0, 0));
1265         }
1266
1267         MultiplyDoubleBySparse(pDbl, _pSparse2, (GenericType**)_pSparseOut);
1268         delete pDbl;
1269         return 0;
1270     }
1271
1272     if (_pSparse2->isScalar())
1273     {
1274         //sp * scalar
1275         Double* pDbl = NULL;
1276         if (_pSparse2->isComplex())
1277         {
1278             std::complex<double> dbl = _pSparse2->getImg(0, 0);
1279             pDbl = new Double(dbl.real(), dbl.imag());
1280         }
1281         else
1282         {
1283             pDbl = new Double(_pSparse2->get(0, 0));
1284         }
1285
1286         MultiplySparseByDouble(_pSparse1, pDbl, (GenericType**)_pSparseOut);
1287         delete pDbl;
1288         return 0;
1289     }
1290
1291     if (_pSparse1->getCols() != _pSparse2->getRows())
1292     {
1293         return 1;
1294     }
1295
1296     *_pSparseOut = _pSparse1->multiply(*_pSparse2);
1297     return 0;
1298 }
1299
1300 int MultiplyDoubleBySparse(Double* _pDouble, Sparse *_pSparse, GenericType** _pOut)
1301 {
1302     //D * SP
1303     if (_pDouble->isScalar())
1304     {
1305         //d * SP -> SP
1306         Sparse* pOut = NULL;
1307         if (_pDouble->isComplex())
1308         {
1309             std::complex<double> dbl(_pDouble->get(0), _pDouble->getImg(0));
1310             pOut = _pSparse->multiply(dbl);
1311         }
1312         else
1313         {
1314             pOut = _pSparse->multiply(_pDouble->get(0));
1315         }
1316         *_pOut = pOut;
1317         return 0;
1318     }
1319
1320     if (_pSparse->isScalar())
1321     {
1322         //D * sp -> D .* d
1323         Double* pD = NULL;
1324
1325         if (_pSparse->isComplex())
1326         {
1327             std::complex<double> dbl(_pSparse->getImg(0, 0));
1328             pD = new Double(dbl.real(), dbl.imag());
1329         }
1330         else
1331         {
1332             pD = new Double(_pSparse->get(0, 0));
1333         }
1334
1335         InternalType* pIT = GenericDotTimes(_pDouble, pD);
1336         *_pOut = pIT->getAs<GenericType>();
1337         delete pD;
1338         return 0;
1339     }
1340
1341     if (_pDouble->getCols() != _pSparse->getRows())
1342     {
1343         return 1;
1344     }
1345
1346     //try to be smart and only compute for non zero values
1347
1348     //get some information
1349     int iNonZeros = static_cast<int>(_pSparse->nonZeros());
1350     int* pRows = new int[iNonZeros * 2];
1351     _pSparse->outputRowCol(pRows);
1352     int* pCols = pRows + iNonZeros;
1353     double* pValR = new double[iNonZeros];
1354     double* pValI = new double[iNonZeros];
1355     _pSparse->outputValues(pValR, pValI);
1356
1357     Double* pOut = new Double(_pDouble->getRows(), _pSparse->getCols(), _pDouble->isComplex() | _pSparse->isComplex());
1358     pOut->setZeros();
1359
1360     if (_pDouble->isComplex() == false && _pSparse->isComplex() == false)
1361     {
1362         for (int i = 0 ; i < iNonZeros ; i++)
1363         {
1364             int iRow = static_cast<int>(pRows[i]) - 1;
1365             int iCol = static_cast<int>(pCols[i]) - 1;
1366             double dbl = pValR[i];
1367
1368             for (int j = 0 ; j < _pDouble->getRows() ; j++)
1369             {
1370                 double dblVal = _pDouble->get(j, iRow) * dbl;
1371                 pOut->set(j, iCol, pOut->get(j, iCol) + dblVal);
1372             }
1373         }
1374     }
1375     else if (_pDouble->isComplex() == false && _pSparse->isComplex() == true)
1376     {
1377         //a * (b ci) -> ab ac
1378         for (int i = 0 ; i < iNonZeros ; i++)
1379         {
1380             int iRow = static_cast<int>(pRows[i]) - 1;
1381             int iCol = static_cast<int>(pCols[i]) - 1;
1382             double dblR = pValR[i];
1383             double dblI = pValI[i];
1384
1385             for (int j = 0 ; j < _pDouble->getRows() ; j++)
1386             {
1387                 double dblValR = _pDouble->get(j, iRow) * dblR;
1388                 double dblValI = _pDouble->get(j, iRow) * dblI;
1389                 pOut->set(j, iCol, pOut->get(j, iCol) + dblValR);
1390                 pOut->setImg(j, iCol, pOut->getImg(j, iCol) + dblValI);
1391             }
1392         }
1393     }
1394     else if (_pDouble->isComplex() == true && _pSparse->isComplex() == false)
1395     {
1396         //(a bi) * c -> ac + bc
1397         for (int i = 0 ; i < iNonZeros ; i++)
1398         {
1399             int iRow = static_cast<int>(pRows[i]) - 1;
1400             int iCol = static_cast<int>(pCols[i]) - 1;
1401             double dblR = pValR[i];
1402
1403             for (int j = 0 ; j < _pDouble->getRows() ; j++)
1404             {
1405                 double dblValR = _pDouble->get(j, iRow) * dblR;
1406                 double dblValI = _pDouble->getImg(j, iRow) * dblR;
1407                 pOut->set(j, iCol, pOut->get(j, iCol) + dblValR);
1408                 pOut->setImg(j, iCol, pOut->getImg(j, iCol) + dblValI);
1409             }
1410         }
1411     }
1412     else if (_pDouble->isComplex() == true && _pSparse->isComplex() == true)
1413     {
1414         for (int i = 0 ; i < iNonZeros ; i++)
1415         {
1416             int iRow = static_cast<int>(pRows[i]) - 1;
1417             int iCol = static_cast<int>(pCols[i]) - 1;
1418             double dblR = pValR[i];
1419             double dblI = pValI[i];
1420
1421             for (int j = 0 ; j < _pDouble->getRows() ; j++)
1422             {
1423                 double dblValR = _pDouble->get(j, iRow) * dblR - _pDouble->getImg(j, iRow) * dblI;
1424                 double dblValI = _pDouble->get(j, iRow) * dblI + _pDouble->getImg(j, iRow) * dblR;
1425                 pOut->set(j, iCol, pOut->get(j, iCol) + dblValR);
1426                 pOut->setImg(j, iCol, pOut->getImg(j, iCol) + dblValI);
1427             }
1428         }
1429     }
1430
1431     *_pOut = pOut;
1432     delete[] pRows;
1433     delete[] pValR;
1434     delete[] pValI;
1435
1436     return 0;
1437 }
1438
1439 int MultiplySparseByDouble(Sparse *_pSparse, Double*_pDouble, GenericType** _pOut)
1440 {
1441     if (_pDouble->isScalar())
1442     {
1443         //SP * d -> SP
1444         Sparse* pOut = NULL;
1445         if (_pDouble->isComplex())
1446         {
1447             std::complex<double> dbl(_pDouble->get(0), _pDouble->getImg(0));
1448             pOut = _pSparse->multiply(dbl);
1449         }
1450         else
1451         {
1452             pOut = _pSparse->multiply(_pDouble->get(0));
1453         }
1454         *_pOut = pOut;
1455         return 0;
1456     }
1457
1458     if (_pSparse->isScalar())
1459     {
1460         //D * sp -> D .* d
1461         Double* pD = NULL;
1462
1463         if (_pSparse->isComplex())
1464         {
1465             std::complex<double> dbl(_pSparse->getImg(0, 0));
1466             pD = new Double(dbl.real(), dbl.imag());
1467         }
1468         else
1469         {
1470             pD = new Double(_pSparse->get(0, 0));
1471         }
1472
1473         InternalType* pIT = GenericDotTimes(_pDouble, pD);
1474         *_pOut = pIT->getAs<GenericType>();
1475         delete pD;
1476         return 0;
1477     }
1478
1479     if (_pSparse->getCols() != _pDouble->getRows())
1480     {
1481         return 1;
1482     }
1483
1484     //try to be smart and only compute for non zero values
1485
1486     //get some information
1487     int iNonZeros = static_cast<int>(_pSparse->nonZeros());
1488     int* pRows = new int[iNonZeros * 2];
1489     _pSparse->outputRowCol(pRows);
1490     int* pCols = pRows + iNonZeros;
1491     double* pValR = new double[iNonZeros];
1492     double* pValI = new double[iNonZeros];
1493     _pSparse->outputValues(pValR, pValI);
1494
1495     Double* pOut = new Double(_pSparse->getRows(), _pDouble->getCols(), _pDouble->isComplex() | _pSparse->isComplex());
1496     pOut->setZeros();
1497
1498     if (_pDouble->isComplex() == false && _pSparse->isComplex() == false)
1499     {
1500         for (int i = 0 ; i < iNonZeros ; i++)
1501         {
1502             int iRow    = static_cast<int>(pRows[i]) - 1;
1503             int iCol    = static_cast<int>(pCols[i]) - 1;
1504             double dbl  = pValR[i];
1505
1506             for (int j = 0 ; j < _pDouble->getCols() ; j++)
1507             {
1508                 double dblVal = _pDouble->get(iCol, j) * dbl;
1509                 pOut->set(iRow, j, pOut->get(iRow, j) + dblVal);
1510             }
1511         }
1512     }
1513     else if (_pDouble->isComplex() == false && _pSparse->isComplex() == true)
1514     {
1515         //a * (b ci) -> ab ac
1516         for (int i = 0 ; i < iNonZeros ; i++)
1517         {
1518             int iRow = static_cast<int>(pRows[i]) - 1;
1519             int iCol = static_cast<int>(pCols[i]) - 1;
1520             double dblR = pValR[i];
1521             double dblI = pValI[i];
1522
1523             for (int j = 0 ; j < _pDouble->getCols() ; j++)
1524             {
1525                 double dblValR = _pDouble->get(iCol, j) * dblR;
1526                 double dblValI = _pDouble->get(iCol, j) * dblI;
1527                 pOut->set(iRow, j, pOut->get(iRow, j) + dblValR);
1528                 pOut->setImg(iRow, j, pOut->getImg(iRow, j) + dblValI);
1529             }
1530         }
1531     }
1532     else if (_pDouble->isComplex() == true && _pSparse->isComplex() == false)
1533     {
1534         //(a bi) * c -> ac + bc
1535         for (int i = 0 ; i < iNonZeros ; i++)
1536         {
1537             int iRow = static_cast<int>(pRows[i]) - 1;
1538             int iCol = static_cast<int>(pCols[i]) - 1;
1539             double dblR = pValR[i];
1540
1541             for (int j = 0 ; j < _pDouble->getCols() ; j++)
1542             {
1543                 double dblValR = _pDouble->get(iCol, j) * dblR;
1544                 double dblValI = _pDouble->getImg(iCol, j) * dblR;
1545                 pOut->set(iRow, j, pOut->get(iRow, j) + dblValR);
1546                 pOut->setImg(iRow, j, pOut->getImg(iRow, j) + dblValI);
1547             }
1548         }
1549     }
1550     else if (_pDouble->isComplex() == true && _pSparse->isComplex() == true)
1551     {
1552         for (int i = 0 ; i < iNonZeros ; i++)
1553         {
1554             int iRow = static_cast<int>(pRows[i]) - 1;
1555             int iCol = static_cast<int>(pCols[i]) - 1;
1556             double dblR = pValR[i];
1557             double dblI = pValI[i];
1558
1559             for (int j = 0 ; j < _pDouble->getCols() ; j++)
1560             {
1561                 double dblValR = _pDouble->get(iCol, j) * dblR - _pDouble->getImg(iCol, j) * dblI;
1562                 double dblValI = _pDouble->get(iCol, j) * dblI + _pDouble->getImg(iCol, j) * dblR;
1563                 pOut->set(iRow, j, pOut->get(iRow, j) + dblValR);
1564                 pOut->setImg(iRow, j, pOut->getImg(iRow, j) + dblValI);
1565             }
1566         }
1567     }
1568
1569     *_pOut = pOut;
1570     delete[] pRows;
1571     delete[] pValR;
1572     delete[] pValI;
1573
1574     return 0;
1575 }
1576
1577 int DotMultiplySparseBySparse(Sparse* _pSparse1, Sparse* _pSparse2, Sparse** _pOut)
1578 {
1579     if (_pSparse1->isScalar() || _pSparse2->isScalar())
1580     {
1581         //SP .* sp or sp .* SP
1582         return MultiplySparseBySparse(_pSparse1, _pSparse2, _pOut);
1583     }
1584
1585     if (_pSparse1->getRows() != _pSparse2->getRows() || _pSparse1->getCols() != _pSparse2->getCols())
1586     {
1587         return 1;
1588     }
1589
1590     *_pOut = _pSparse1->dotMultiply(*_pSparse2);
1591
1592     return 0;
1593 }
1594
1595 int DotMultiplyDoubleBySparse(Double* _pDouble, Sparse* _pSparse, GenericType**  _pOut)
1596 {
1597     if (_pDouble->isScalar())
1598     {
1599         return MultiplyDoubleBySparse(_pDouble, _pSparse, _pOut);
1600     }
1601
1602     if (_pSparse->isScalar())
1603     {
1604         return MultiplyDoubleBySparse(_pDouble, _pSparse, _pOut);
1605     }
1606
1607     if (_pSparse->getRows() != _pDouble->getRows() || _pSparse->getCols() != _pDouble->getCols())
1608     {
1609         return 1;
1610     }
1611
1612     Sparse* pOut = new Sparse(_pDouble->getRows(), _pDouble->getCols(), _pSparse->isComplex() || _pDouble->isComplex());
1613     //get some information
1614     int iNonZeros = static_cast<int>(_pSparse->nonZeros());
1615     int* pRows = new int[iNonZeros * 2];
1616     _pSparse->outputRowCol(pRows);
1617     int* pCols = pRows + iNonZeros;
1618
1619     if (_pDouble->isComplex() == false && _pSparse->isComplex() == false)
1620     {
1621         for (int i = 0 ; i < iNonZeros ; i++)
1622         {
1623             int iRow = static_cast<int>(pRows[i]) - 1;
1624             int iCol = static_cast<int>(pCols[i]) - 1;
1625             pOut->set(iRow, iCol, _pSparse->get(iRow, iCol) * _pDouble->get(iRow, iCol));
1626         }
1627     }
1628     else if (_pDouble->isComplex() == false && _pSparse->isComplex() == true)
1629     {
1630         for (int i = 0 ; i < iNonZeros ; i++)
1631         {
1632             int iRow = static_cast<int>(pRows[i]) - 1;
1633             int iCol = static_cast<int>(pCols[i]) - 1;
1634             std::complex<double> dbl = _pSparse->getImg(iRow, iCol);
1635             std::complex<double> newVal(dbl.real() * _pDouble->get(iRow, iCol), dbl.imag() * _pDouble->get(iRow, iCol));
1636             pOut->set(iRow, iCol, newVal);
1637         }
1638     }
1639     else if (_pDouble->isComplex() == true && _pSparse->isComplex() == false)
1640     {
1641         for (int i = 0 ; i < iNonZeros ; i++)
1642         {
1643             int iRow = static_cast<int>(pRows[i]) - 1;
1644             int iCol = static_cast<int>(pCols[i]) - 1;
1645             std::complex<double> dbl = _pSparse->getImg(iRow, iCol);
1646             std::complex<double> newVal(dbl.real() * _pDouble->get(iRow, iCol), dbl.real() * _pDouble->getImg(iRow, iCol));
1647             pOut->set(iRow, iCol, newVal);
1648         }
1649     }
1650     else if (_pDouble->isComplex() == true && _pSparse->isComplex() == true)
1651     {
1652         for (int i = 0 ; i < iNonZeros ; i++)
1653         {
1654             int iRow = static_cast<int>(pRows[i]) - 1;
1655             int iCol = static_cast<int>(pCols[i]) - 1;
1656             std::complex<double> dbl = _pSparse->getImg(iRow, iCol);
1657             double dblR = _pDouble->get(iRow, iCol) * dbl.real() - _pDouble->getImg(iRow, iCol) * dbl.imag();
1658             double dblI = _pDouble->getImg(iRow, iCol) * dbl.real() + _pDouble->get(iRow, iCol) * dbl.imag();
1659
1660             std::complex<double> newVal(dblR, dblI);
1661             pOut->set(iRow, iCol, newVal);
1662         }
1663     }
1664
1665     *_pOut = pOut;
1666     delete[] pRows;
1667
1668     return 0;
1669 }
1670
1671 int DotMultiplySparseByDouble(Sparse* _pSparse, Double* _pDouble, GenericType** _pOut)
1672 {
1673     return DotMultiplyDoubleBySparse(_pDouble, _pSparse, _pOut);
1674 }
1675
1676 int DotMultiplyPolyByDouble(Polynom* _pPoly, Double* _pDouble, Polynom** _pPolyOut)
1677 {
1678     return DotMultiplyDoubleByPoly(_pDouble, _pPoly, _pPolyOut);
1679 }
1680
1681 int DotMultiplyDoubleByPoly(Double* _pDouble, Polynom* _pPoly, Polynom** _pPolyOut)
1682 {
1683     if (_pDouble->isScalar() == false &&
1684             _pPoly->isScalar() == false &&
1685             _pDouble->getSize() != _pPoly->getSize())
1686     {
1687         return 1;
1688     }
1689
1690     Polynom* pPolyTemp = new Polynom(_pPoly->getVariableName(), _pDouble->getDims(), _pDouble->getDimsArray());
1691     pPolyTemp->setCoef(_pDouble);
1692     int iErr = DotMultiplyPolyByPoly(pPolyTemp, _pPoly, _pPolyOut);
1693     delete pPolyTemp;
1694     return iErr;
1695 }
1696
1697 int DotMultiplyPolyByPoly(Polynom* _pPoly1, Polynom* _pPoly2, Polynom** _pPolyOut)
1698 {
1699     if (_pPoly1->isScalar() || _pPoly2->isScalar())
1700     {
1701         return MultiplyPolyByPoly(_pPoly1, _pPoly2, _pPolyOut);
1702     }
1703     else
1704     {
1705         if (_pPoly1->getSize() != _pPoly2->getSize())
1706         {
1707             return 1;
1708         }
1709
1710         int* piRank = new int[_pPoly1->getSize()];
1711         for (int i = 0 ; i < _pPoly1->getSize() ; i++)
1712         {
1713             piRank[i] = _pPoly1->get(i)->getRank() + _pPoly2->get(i)->getRank() - 1;
1714         }
1715
1716         (*_pPolyOut) = new Polynom(_pPoly1->getVariableName(), _pPoly1->getDims(), _pPoly1->getDimsArray(), piRank);
1717
1718         if (_pPoly1->isComplex() && _pPoly2->isComplex())
1719         {
1720             (*_pPolyOut)->setComplex(true);
1721             for (int i = 0; i < _pPoly1->getSize(); i++)
1722             {
1723                 SinglePoly *pSP1    = _pPoly1->get(i);
1724                 SinglePoly *pSP2    = _pPoly2->get(i);
1725                 SinglePoly *pSPOut  = (*_pPolyOut)->get(i);
1726                 Double *pCoef1      = pSP1->getCoef();
1727                 Double *pCoef2      = pSP2->getCoef();
1728                 Double *pCoefOut    = pSPOut->getCoef();
1729
1730                 pCoefOut->setZeros();
1731
1732                 iMultiComplexPolyByComplexPoly(
1733                     pCoef1->get(), pCoef1->getImg(), pSP1->getRank(),
1734                     pCoef2->get(), pCoef2->getImg(), pSP2->getRank(),
1735                     pCoefOut->get(), pCoefOut->getImg(), pSPOut->getRank());
1736
1737             }
1738         }
1739         else if (_pPoly1->isComplex())
1740         {
1741             (*_pPolyOut)->setComplex(true);
1742             for (int i = 0; i < _pPoly1->getSize(); i++)
1743             {
1744                 SinglePoly *pSP1   = _pPoly1->get(i);
1745                 SinglePoly *pSP2   = _pPoly2->get(i);
1746                 SinglePoly *pSPOut = (*_pPolyOut)->get(i);
1747
1748                 pSPOut->getCoef()->setZeros();
1749
1750                 iMultiComplexPolyByScilabPolynom(
1751                     pSP1->getCoef()->get(), pSP1->getCoef()->getImg(), pSP1->getRank(),
1752                     pSP2->getCoef()->get(), pSP2->getRank(),
1753                     pSPOut->getCoef()->get(), pSPOut->getCoef()->getImg(), pSPOut->getRank());
1754             }
1755         }
1756         else if (_pPoly2->isComplex())
1757         {
1758             (*_pPolyOut)->setComplex(true);
1759             for (int i = 0; i < _pPoly1->getSize(); i++)
1760             {
1761                 SinglePoly *pSP1   = _pPoly1->get(i);
1762                 SinglePoly *pSP2   = _pPoly2->get(i);
1763                 SinglePoly *pSPOut = (*_pPolyOut)->get(i);
1764
1765                 pSPOut->getCoef()->setZeros();
1766
1767                 iMultiScilabPolynomByComplexPoly(
1768                     pSP1->getCoef()->get(), pSP1->getRank(),
1769                     pSP2->getCoef()->get(), pSP2->getCoef()->getImg(), pSP2->getRank(),
1770                     pSPOut->getCoef()->get(), pSPOut->getCoef()->getImg(), pSPOut->getRank());
1771             }
1772         }
1773         else
1774         {
1775             for (int i = 0; i < _pPoly1->getSize(); i++)
1776             {
1777                 SinglePoly *pSP1   = _pPoly1->get(i);
1778                 SinglePoly *pSP2   = _pPoly2->get(i);
1779                 SinglePoly *pSPOut = (*_pPolyOut)->get(i);
1780
1781                 pSPOut->getCoef()->setZeros();
1782
1783                 iMultiScilabPolynomByScilabPolynom(
1784                     pSP1->getCoef()->get(), pSP1->getRank(),
1785                     pSP2->getCoef()->get(), pSP2->getRank(),
1786                     pSPOut->getCoef()->get(), pSPOut->getRank());
1787             }
1788         }
1789     }
1790
1791     return 0;
1792 }