bug 13918: Unmanaged operations on hypermatrix did not call overload functions.
[scilab.git] / scilab / modules / ast / src / cpp / operations / types_addition.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 <algorithm>
15 #include "types_addition.hxx"
16 #include "operations.hxx"
17 #include "double.hxx"
18 #include "int.hxx"
19
20 extern "C"
21 {
22 #include "matrix_addition.h"
23 #include "elem_common.h" //dset
24 #include "Sciwarning.h"
25 }
26
27 using namespace types;
28 //define arrays on operation functions
29 static add_function pAddfunction[types::InternalType::IdLast][types::InternalType::IdLast] = {NULL};
30
31 void fillAddFunction()
32 {
33 #define scilab_fill_add(id1, id2, func, typeIn1, typeIn2, typeOut) \
34     pAddfunction[types::InternalType::Id ## id1][types::InternalType::Id ## id2] = (add_function)&add_##func<typeIn1, typeIn2, typeOut>
35
36     //Double
37     //Matrix + Matrix
38     scilab_fill_add(Double, Double, M_M, Double, Double, Double);
39     scilab_fill_add(Double, Int8, M_M, Double, Int8, Int8);
40     scilab_fill_add(Double, UInt8, M_M, Double, UInt8, UInt8);
41     scilab_fill_add(Double, Int16, M_M, Double, Int16, Int16);
42     scilab_fill_add(Double, UInt16, M_M, Double, UInt16, UInt16);
43     scilab_fill_add(Double, Int32, M_M, Double, Int32, Int32);
44     scilab_fill_add(Double, UInt32, M_M, Double, UInt32, UInt32);
45     scilab_fill_add(Double, Int64, M_M, Double, Int64, Int64);
46     scilab_fill_add(Double, UInt64, M_M, Double, UInt64, UInt64);
47     scilab_fill_add(Double, Bool, M_M, Double, Bool, Double);
48     scilab_fill_add(Double, Polynom, M_M, Double, Polynom, Polynom);
49     scilab_fill_add(Double, Sparse, M_M, Double, Sparse, Double);
50
51     //Matrix + Matrix Complex
52     scilab_fill_add(Double, DoubleComplex, M_MC, Double, Double, Double);
53     scilab_fill_add(Double, PolynomComplex, M_M, Double, Polynom, Polynom);
54     scilab_fill_add(Double, SparseComplex, M_M, Double, Sparse, Double);
55
56     //Matrix + Scalar
57     scilab_fill_add(Double, ScalarDouble, M_S, Double, Double, Double);
58     scilab_fill_add(Double, ScalarInt8, M_S, Double, Int8, Int8);
59     scilab_fill_add(Double, ScalarUInt8, M_S, Double, UInt8, UInt8);
60     scilab_fill_add(Double, ScalarInt16, M_S, Double, Int16, Int16);
61     scilab_fill_add(Double, ScalarUInt16, M_S, Double, UInt16, UInt16);
62     scilab_fill_add(Double, ScalarInt32, M_S, Double, Int32, Int32);
63     scilab_fill_add(Double, ScalarUInt32, M_S, Double, UInt32, UInt32);
64     scilab_fill_add(Double, ScalarInt64, M_S, Double, Int64, Int64);
65     scilab_fill_add(Double, ScalarUInt64, M_S, Double, UInt64, UInt64);
66     scilab_fill_add(Double, ScalarBool, M_S, Double, Bool, Double);
67     scilab_fill_add(Double, ScalarPolynom, M_M, Double, Polynom, Polynom);
68
69     //Matrix + Scalar Complex
70     scilab_fill_add(Double, ScalarDoubleComplex, M_SC, Double, Double, Double);
71     scilab_fill_add(Double, ScalarPolynomComplex, M_M, Double, Polynom, Polynom);
72     //Matrix + Empty
73     scilab_fill_add(Double, Empty, M_E, Double, Double, Double);
74
75
76     //Matrix Complex + Matrix
77     scilab_fill_add(DoubleComplex, Double, MC_M, Double, Double, Double);
78     scilab_fill_add(DoubleComplex, DoubleComplex, MC_MC, Double, Double, Double);
79     scilab_fill_add(DoubleComplex, ScalarDouble, MC_S, Double, Double, Double);
80     scilab_fill_add(DoubleComplex, ScalarDoubleComplex, MC_SC, Double, Double, Double);
81     scilab_fill_add(DoubleComplex, Empty, MC_E, Double, Double, Double);
82     scilab_fill_add(DoubleComplex, Polynom, M_M, Double, Polynom, Polynom);
83     scilab_fill_add(DoubleComplex, PolynomComplex, M_M, Double, Polynom, Polynom);
84     scilab_fill_add(DoubleComplex, ScalarPolynom, M_M, Double, Polynom, Polynom);
85     scilab_fill_add(DoubleComplex, ScalarPolynomComplex, M_M, Double, Polynom, Polynom);
86     scilab_fill_add(DoubleComplex, Sparse, M_M, Double, Sparse, Double);
87     scilab_fill_add(DoubleComplex, SparseComplex, M_M, Double, Sparse, Double);
88
89     //Scalar + Matrix
90     scilab_fill_add(ScalarDouble, Double, S_M, Double, Double, Double);
91     scilab_fill_add(ScalarDouble, Int8, S_M, Double, Int8, Int8);
92     scilab_fill_add(ScalarDouble, UInt8, S_M, Double, UInt8, UInt8);
93     scilab_fill_add(ScalarDouble, Int16, S_M, Double, Int16, Int16);
94     scilab_fill_add(ScalarDouble, UInt16, S_M, Double, UInt16, UInt16);
95     scilab_fill_add(ScalarDouble, Int32, S_M, Double, Int32, Int32);
96     scilab_fill_add(ScalarDouble, UInt32, S_M, Double, UInt32, UInt32);
97     scilab_fill_add(ScalarDouble, Int64, S_M, Double, Int64, Int64);
98     scilab_fill_add(ScalarDouble, UInt64, S_M, Double, UInt64, UInt64);
99     scilab_fill_add(ScalarDouble, Bool, S_M, Double, Bool, Double);
100     scilab_fill_add(ScalarDouble, Polynom, M_M, Double, Polynom, Polynom);
101     scilab_fill_add(ScalarDouble, Sparse, M_M, Double, Sparse, Double);
102
103     //Scalar + Matrix Complex
104     scilab_fill_add(ScalarDouble, DoubleComplex, S_MC, Double, Double, Double);
105     scilab_fill_add(ScalarDouble, PolynomComplex, M_M, Double, Polynom, Polynom);
106     scilab_fill_add(ScalarDouble, SparseComplex, M_M, Double, Sparse, Double);
107
108     //Scalar + Scalar
109     scilab_fill_add(ScalarDouble, ScalarDouble, S_S, Double, Double, Double);
110     scilab_fill_add(ScalarDouble, ScalarInt8, S_S, Double, Int8, Int8);
111     scilab_fill_add(ScalarDouble, ScalarUInt8, S_S, Double, UInt8, UInt8);
112     scilab_fill_add(ScalarDouble, ScalarInt16, S_S, Double, Int16, Int16);
113     scilab_fill_add(ScalarDouble, ScalarUInt16, S_S, Double, UInt16, UInt16);
114     scilab_fill_add(ScalarDouble, ScalarInt32, S_S, Double, Int32, Int32);
115     scilab_fill_add(ScalarDouble, ScalarUInt32, S_S, Double, UInt32, UInt32);
116     scilab_fill_add(ScalarDouble, ScalarInt64, S_S, Double, Int64, Int64);
117     scilab_fill_add(ScalarDouble, ScalarUInt64, S_S, Double, UInt64, UInt64);
118     scilab_fill_add(ScalarDouble, ScalarBool, S_S, Double, Bool, Double);
119     scilab_fill_add(ScalarDouble, ScalarPolynom, M_M, Double, Polynom, Polynom);
120
121     //Scalar + Scalar Complex
122     scilab_fill_add(ScalarDouble, ScalarDoubleComplex, S_SC, Double, Double, Double);
123     scilab_fill_add(ScalarDouble, PolynomComplex, M_M, Double, Polynom, Polynom);
124     scilab_fill_add(ScalarDouble, ScalarPolynomComplex, M_M, Double, Polynom, Polynom);
125
126     //Scalar + Empty
127     scilab_fill_add(ScalarDouble, Empty, S_E, Double, Double, Double);
128
129     //Scalar Complex + Matrix
130     scilab_fill_add(ScalarDoubleComplex, Double, SC_M, Double, Double, Double);
131     scilab_fill_add(ScalarDoubleComplex, Polynom, M_M, Double, Polynom, Polynom);
132     scilab_fill_add(ScalarDoubleComplex, Sparse, M_M, Double, Sparse, Double);
133     //Scalar Complex + Matrix Complex
134     scilab_fill_add(ScalarDoubleComplex, DoubleComplex, SC_MC, Double, Double, Double);
135     scilab_fill_add(ScalarDoubleComplex, PolynomComplex, M_M, Double, Polynom, Polynom);
136     scilab_fill_add(ScalarDoubleComplex, SparseComplex, M_M, Double, Sparse, Double);
137     //Scalar Complex + Scalar
138     scilab_fill_add(ScalarDoubleComplex, ScalarDouble, SC_S, Double, Double, Double);
139     scilab_fill_add(ScalarDoubleComplex, ScalarPolynom, M_M, Double, Polynom, Polynom);
140     //Scalar Complex + Scalar Complex
141     scilab_fill_add(ScalarDoubleComplex, ScalarDoubleComplex, SC_SC, Double, Double, Double);
142     scilab_fill_add(ScalarDoubleComplex, ScalarPolynomComplex, M_M, Double, Polynom, Polynom);
143     //Scalar Complex + Empty
144     scilab_fill_add(ScalarDoubleComplex, Empty, SC_E, Double, Double, Double);
145
146     //Empty + Matrix
147     scilab_fill_add(Empty, Double, E_M, Double, Double, Double);
148     scilab_fill_add(Empty, Int8, E_M, Double, Int8, Int8);
149     scilab_fill_add(Empty, UInt8, E_M, Double, UInt8, UInt8);
150     scilab_fill_add(Empty, Int16, E_M, Double, Int16, Int16);
151     scilab_fill_add(Empty, UInt16, E_M, Double, UInt16, UInt16);
152     scilab_fill_add(Empty, Int32, E_M, Double, Int32, Int32);
153     scilab_fill_add(Empty, UInt32, E_M, Double, UInt32, UInt32);
154     scilab_fill_add(Empty, Int64, E_M, Double, Int64, Int64);
155     scilab_fill_add(Empty, UInt64, E_M, Double, UInt64, UInt64);
156     scilab_fill_add(Empty, Bool, E_M, Double, Bool, Double);
157     scilab_fill_add(Empty, String, E_M, Double, String, String);
158     scilab_fill_add(Empty, Polynom, E_M, Double, Polynom, Polynom);
159     scilab_fill_add(Empty, PolynomComplex, E_M, Double, Polynom, Polynom);
160     scilab_fill_add(Empty, Sparse, E_M, Double, Sparse, Sparse);
161     scilab_fill_add(Empty, SparseComplex, E_M, Double, Sparse, Sparse);
162
163     //Empty + Matrix Complex
164     scilab_fill_add(Empty, DoubleComplex, E_MC, Double, Double, Double);
165     //Empty + Scalar
166     scilab_fill_add(Empty, ScalarDouble, E_S, Double, Double, Double);
167     scilab_fill_add(Empty, ScalarInt8, E_S, Double, Int8, Int8);
168     scilab_fill_add(Empty, ScalarUInt8, E_S, Double, UInt8, UInt8);
169     scilab_fill_add(Empty, ScalarInt16, E_S, Double, Int16, Int16);
170     scilab_fill_add(Empty, ScalarUInt16, E_S, Double, UInt16, UInt16);
171     scilab_fill_add(Empty, ScalarInt32, E_S, Double, Int32, Int32);
172     scilab_fill_add(Empty, ScalarUInt32, E_S, Double, UInt32, UInt32);
173     scilab_fill_add(Empty, ScalarInt64, E_S, Double, Int64, Int64);
174     scilab_fill_add(Empty, ScalarUInt64, E_S, Double, UInt64, UInt64);
175     scilab_fill_add(Empty, ScalarBool, E_S, Double, Bool, Double);
176     scilab_fill_add(Empty, ScalarString, E_S, Double, String, String);
177     scilab_fill_add(Empty, ScalarPolynom, E_S, Double, Polynom, Polynom);
178
179     //Empty + Scalar Complex
180     scilab_fill_add(Empty, ScalarDoubleComplex, E_SC, Double, Double, Double);
181     scilab_fill_add(Empty, ScalarPolynomComplex, E_M, Double, Polynom, Polynom);
182     //Empty + Empty
183     scilab_fill_add(Empty, Empty, E_E, Double, Double, Double);
184     //Empty + eye
185     scilab_fill_add(Empty, Identity, E_I, Double, Double, Double);
186     scilab_fill_add(Empty, IdentityComplex, E_IC, Double, Double, Double);
187
188     //Matrix + Identity
189     scilab_fill_add(Double, Identity, M_I, Double, Double, Double);
190     scilab_fill_add(Double, IdentityComplex, M_IC, Double, Double, Double);
191     scilab_fill_add(DoubleComplex, Identity, MC_I, Double, Double, Double);
192     scilab_fill_add(DoubleComplex, IdentityComplex, MC_IC, Double, Double, Double);
193     scilab_fill_add(ScalarDouble, Identity, S_I, Double, Double, Double);
194     scilab_fill_add(ScalarDouble, IdentityComplex, S_IC, Double, Double, Double);
195     scilab_fill_add(ScalarDoubleComplex, Identity, SC_I, Double, Double, Double);
196     scilab_fill_add(ScalarDoubleComplex, IdentityComplex, SC_IC, Double, Double, Double);
197
198
199     //Int8
200     //Matrix + Matrix
201     scilab_fill_add(Int8, Double, M_M, Int8, Double, Int8);
202     scilab_fill_add(Int8, Int8, M_M, Int8, Int8, Int8);
203     scilab_fill_add(Int8, UInt8, M_M, Int8, UInt8, UInt8);
204     scilab_fill_add(Int8, Int16, M_M, Int8, Int16, Int16);
205     scilab_fill_add(Int8, UInt16, M_M, Int8, UInt16, UInt16);
206     scilab_fill_add(Int8, Int32, M_M, Int8, Int32, Int32);
207     scilab_fill_add(Int8, UInt32, M_M, Int8, UInt32, UInt32);
208     scilab_fill_add(Int8, Int64, M_M, Int8, Int64, Int64);
209     scilab_fill_add(Int8, UInt64, M_M, Int8, UInt64, UInt64);
210     scilab_fill_add(Int8, Bool, M_M, Int8, Bool, Int8);
211     scilab_fill_add(Int8, Empty, M_E, Int8, Double, Int8);
212
213     //Matrix + Scalar
214     scilab_fill_add(Int8, ScalarDouble, M_S, Int8, Double, Int8);
215     scilab_fill_add(Int8, ScalarInt8, M_S, Int8, Int8, Int8);
216     scilab_fill_add(Int8, ScalarUInt8, M_S, Int8, UInt8, UInt8);
217     scilab_fill_add(Int8, ScalarInt16, M_S, Int8, Int16, Int16);
218     scilab_fill_add(Int8, ScalarUInt16, M_S, Int8, UInt16, UInt16);
219     scilab_fill_add(Int8, ScalarInt32, M_S, Int8, Int32, Int32);
220     scilab_fill_add(Int8, ScalarUInt32, M_S, Int8, UInt32, UInt32);
221     scilab_fill_add(Int8, ScalarInt64, M_S, Int8, Int64, Int64);
222     scilab_fill_add(Int8, ScalarUInt64, M_S, Int8, UInt64, UInt64);
223     scilab_fill_add(Int8, ScalarBool, M_S, Int8, Bool, Int8);
224
225     //Scalar + Matrix
226     scilab_fill_add(ScalarInt8, Double, S_M, Int8, Double, Int8);
227     scilab_fill_add(ScalarInt8, Int8, S_M, Int8, Int8, Int8);
228     scilab_fill_add(ScalarInt8, UInt8, S_M, Int8, UInt8, UInt8);
229     scilab_fill_add(ScalarInt8, Int16, S_M, Int8, Int16, Int16);
230     scilab_fill_add(ScalarInt8, UInt16, S_M, Int8, UInt16, UInt16);
231     scilab_fill_add(ScalarInt8, Int32, S_M, Int8, Int32, Int32);
232     scilab_fill_add(ScalarInt8, UInt32, S_M, Int8, UInt32, UInt32);
233     scilab_fill_add(ScalarInt8, Int64, S_M, Int8, Int64, Int64);
234     scilab_fill_add(ScalarInt8, UInt64, S_M, Int8, UInt64, UInt64);
235     scilab_fill_add(ScalarInt8, Bool, S_M, Int8, Bool, Int8);
236     scilab_fill_add(ScalarInt8, Empty, S_E, Int8, Double, Int8);
237
238     //Scalar + Scalar
239     scilab_fill_add(ScalarInt8, ScalarDouble, S_S, Int8, Double, Int8);
240     scilab_fill_add(ScalarInt8, ScalarInt8, S_S, Int8, Int8, Int8);
241     scilab_fill_add(ScalarInt8, ScalarUInt8, S_S, Int8, UInt8, UInt8);
242     scilab_fill_add(ScalarInt8, ScalarInt16, S_S, Int8, Int16, Int16);
243     scilab_fill_add(ScalarInt8, ScalarUInt16, S_S, Int8, UInt16, UInt16);
244     scilab_fill_add(ScalarInt8, ScalarInt32, S_S, Int8, Int32, Int32);
245     scilab_fill_add(ScalarInt8, ScalarUInt32, S_S, Int8, UInt32, UInt32);
246     scilab_fill_add(ScalarInt8, ScalarInt64, S_S, Int8, Int64, Int64);
247     scilab_fill_add(ScalarInt8, ScalarUInt64, S_S, Int8, UInt64, UInt64);
248     scilab_fill_add(ScalarInt8, ScalarBool, S_S, Int8, Bool, Int8);
249
250     //UInt8
251     //Matrix + Matrix
252     scilab_fill_add(UInt8, Double, M_M, UInt8, Double, UInt8);
253     scilab_fill_add(UInt8, Int8, M_M, UInt8, Int8, UInt8);
254     scilab_fill_add(UInt8, UInt8, M_M, UInt8, UInt8, UInt8);
255     scilab_fill_add(UInt8, Int16, M_M, UInt8, Int16, UInt16);
256     scilab_fill_add(UInt8, UInt16, M_M, UInt8, UInt16, UInt16);
257     scilab_fill_add(UInt8, Int32, M_M, UInt8, Int32, UInt32);
258     scilab_fill_add(UInt8, UInt32, M_M, UInt8, UInt32, UInt32);
259     scilab_fill_add(UInt8, Int64, M_M, UInt8, Int64, UInt64);
260     scilab_fill_add(UInt8, UInt64, M_M, UInt8, UInt64, UInt64);
261     scilab_fill_add(UInt8, Bool, M_M, UInt8, Bool, UInt8);
262     scilab_fill_add(UInt8, Empty, M_E, UInt8, Double, UInt8);
263
264     //Matrix + Scalar
265     scilab_fill_add(UInt8, ScalarDouble, M_S, UInt8, Double, UInt8);
266     scilab_fill_add(UInt8, ScalarInt8, M_S, UInt8, Int8, UInt8);
267     scilab_fill_add(UInt8, ScalarUInt8, M_S, UInt8, UInt8, UInt8);
268     scilab_fill_add(UInt8, ScalarInt16, M_S, UInt8, Int16, UInt16);
269     scilab_fill_add(UInt8, ScalarUInt16, M_S, UInt8, UInt16, UInt16);
270     scilab_fill_add(UInt8, ScalarInt32, M_S, UInt8, Int32, UInt32);
271     scilab_fill_add(UInt8, ScalarUInt32, M_S, UInt8, UInt32, UInt32);
272     scilab_fill_add(UInt8, ScalarInt64, M_S, UInt8, Int64, UInt64);
273     scilab_fill_add(UInt8, ScalarUInt64, M_S, UInt8, UInt64, UInt64);
274     scilab_fill_add(UInt8, ScalarBool, M_S, UInt8, Bool, UInt8);
275
276     //Scalar + Matrix
277     scilab_fill_add(ScalarUInt8, Double, S_M, UInt8, Double, UInt8);
278     scilab_fill_add(ScalarUInt8, Int8, S_M, UInt8, Int8, UInt8);
279     scilab_fill_add(ScalarUInt8, UInt8, S_M, UInt8, UInt8, UInt8);
280     scilab_fill_add(ScalarUInt8, Int16, S_M, UInt8, Int16, UInt16);
281     scilab_fill_add(ScalarUInt8, UInt16, S_M, UInt8, UInt16, UInt16);
282     scilab_fill_add(ScalarUInt8, Int32, S_M, UInt8, Int32, UInt32);
283     scilab_fill_add(ScalarUInt8, UInt32, S_M, UInt8, UInt32, UInt32);
284     scilab_fill_add(ScalarUInt8, Int64, S_M, UInt8, Int64, UInt64);
285     scilab_fill_add(ScalarUInt8, UInt64, S_M, UInt8, UInt64, UInt64);
286     scilab_fill_add(ScalarUInt8, Bool, S_M, UInt8, Bool, UInt8);
287     scilab_fill_add(ScalarUInt8, Empty, S_E, UInt8, Double, UInt8);
288
289     //Scalar + Scalar
290     scilab_fill_add(ScalarUInt8, ScalarDouble, S_S, UInt8, Double, UInt8);
291     scilab_fill_add(ScalarUInt8, ScalarInt8, S_S, UInt8, Int8, UInt8);
292     scilab_fill_add(ScalarUInt8, ScalarUInt8, S_S, UInt8, UInt8, UInt8);
293     scilab_fill_add(ScalarUInt8, ScalarInt16, S_S, UInt8, Int16, UInt16);
294     scilab_fill_add(ScalarUInt8, ScalarUInt16, S_S, UInt8, UInt16, UInt16);
295     scilab_fill_add(ScalarUInt8, ScalarInt32, S_S, UInt8, Int32, UInt32);
296     scilab_fill_add(ScalarUInt8, ScalarUInt32, S_S, UInt8, UInt32, UInt32);
297     scilab_fill_add(ScalarUInt8, ScalarInt64, S_S, UInt8, Int64, UInt64);
298     scilab_fill_add(ScalarUInt8, ScalarUInt64, S_S, UInt8, UInt64, UInt64);
299     scilab_fill_add(ScalarUInt8, ScalarBool, S_S, UInt8, Bool, UInt8);
300
301     //Int16
302     //Matrix + Matrix
303     scilab_fill_add(Int16, Double, M_M, Int16, Double, Int16);
304     scilab_fill_add(Int16, Int8, M_M, Int16, Int8, Int16);
305     scilab_fill_add(Int16, UInt8, M_M, Int16, UInt8, UInt16);
306     scilab_fill_add(Int16, Int16, M_M, Int16, Int16, Int16);
307     scilab_fill_add(Int16, UInt16, M_M, Int16, UInt16, UInt16);
308     scilab_fill_add(Int16, Int32, M_M, Int16, Int32, Int32);
309     scilab_fill_add(Int16, UInt32, M_M, Int16, UInt32, UInt32);
310     scilab_fill_add(Int16, Int64, M_M, Int16, Int64, Int64);
311     scilab_fill_add(Int16, UInt64, M_M, Int16, UInt64, UInt64);
312     scilab_fill_add(Int16, Bool, M_M, Int16, Bool, Int16);
313     scilab_fill_add(Int16, Empty, M_E, Int16, Double, Int16);
314
315     //Matrix + Scalar
316     scilab_fill_add(Int16, ScalarDouble, M_S, Int16, Double, Int16);
317     scilab_fill_add(Int16, ScalarInt8, M_S, Int16, Int8, Int16);
318     scilab_fill_add(Int16, ScalarUInt8, M_S, Int16, UInt8, UInt16);
319     scilab_fill_add(Int16, ScalarInt16, M_S, Int16, Int16, Int16);
320     scilab_fill_add(Int16, ScalarUInt16, M_S, Int16, UInt16, UInt16);
321     scilab_fill_add(Int16, ScalarInt32, M_S, Int16, Int32, Int32);
322     scilab_fill_add(Int16, ScalarUInt32, M_S, Int16, UInt32, UInt32);
323     scilab_fill_add(Int16, ScalarInt64, M_S, Int16, Int64, Int64);
324     scilab_fill_add(Int16, ScalarUInt64, M_S, Int16, UInt64, UInt64);
325     scilab_fill_add(Int16, ScalarBool, M_S, Int16, Bool, Int16);
326
327     //Scalar + Matrix
328     scilab_fill_add(ScalarInt16, Double, S_M, Int16, Double, Int16);
329     scilab_fill_add(ScalarInt16, Int8, S_M, Int16, Int8, Int16);
330     scilab_fill_add(ScalarInt16, UInt8, S_M, Int16, UInt8, UInt16);
331     scilab_fill_add(ScalarInt16, Int16, S_M, Int16, Int16, Int16);
332     scilab_fill_add(ScalarInt16, UInt16, S_M, Int16, UInt16, UInt16);
333     scilab_fill_add(ScalarInt16, Int32, S_M, Int16, Int32, Int32);
334     scilab_fill_add(ScalarInt16, UInt32, S_M, Int16, UInt32, UInt32);
335     scilab_fill_add(ScalarInt16, Int64, S_M, Int16, Int64, Int64);
336     scilab_fill_add(ScalarInt16, UInt64, S_M, Int16, UInt64, UInt64);
337     scilab_fill_add(ScalarInt16, Bool, S_M, Int16, Bool, Int16);
338     scilab_fill_add(ScalarInt16, Empty, S_E, Int16, Double, Int16);
339
340     //Scalar + Scalar
341     scilab_fill_add(ScalarInt16, ScalarDouble, S_S, Int16, Double, Int16);
342     scilab_fill_add(ScalarInt16, ScalarInt8, S_S, Int16, Int8, Int16);
343     scilab_fill_add(ScalarInt16, ScalarUInt8, S_S, Int16, UInt8, UInt16);
344     scilab_fill_add(ScalarInt16, ScalarInt16, S_S, Int16, Int16, Int16);
345     scilab_fill_add(ScalarInt16, ScalarUInt16, S_S, Int16, UInt16, UInt16);
346     scilab_fill_add(ScalarInt16, ScalarInt32, S_S, Int16, Int32, Int32);
347     scilab_fill_add(ScalarInt16, ScalarUInt32, S_S, Int16, UInt32, UInt32);
348     scilab_fill_add(ScalarInt16, ScalarInt64, S_S, Int16, Int64, Int64);
349     scilab_fill_add(ScalarInt16, ScalarUInt64, S_S, Int16, UInt64, UInt64);
350     scilab_fill_add(ScalarInt16, ScalarBool, S_S, Int16, Bool, Int16);
351
352     //UInt16
353     //Matrix + Matrix
354     scilab_fill_add(UInt16, Double, M_M, UInt16, Double, UInt16);
355     scilab_fill_add(UInt16, Int8, M_M, UInt16, Int8, UInt16);
356     scilab_fill_add(UInt16, UInt8, M_M, UInt16, UInt8, UInt16);
357     scilab_fill_add(UInt16, Int16, M_M, UInt16, Int16, UInt16);
358     scilab_fill_add(UInt16, UInt16, M_M, UInt16, UInt16, UInt16);
359     scilab_fill_add(UInt16, Int32, M_M, UInt16, Int32, UInt32);
360     scilab_fill_add(UInt16, UInt32, M_M, UInt16, UInt32, UInt32);
361     scilab_fill_add(UInt16, Int64, M_M, UInt16, Int64, UInt64);
362     scilab_fill_add(UInt16, UInt64, M_M, UInt16, UInt64, UInt64);
363     scilab_fill_add(UInt16, Bool, M_M, UInt16, Bool, UInt16);
364     scilab_fill_add(UInt16, Empty, M_E, UInt16, Double, UInt16);
365
366     //Matrix + Scalar
367     scilab_fill_add(UInt16, ScalarDouble, M_S, UInt16, Double, UInt16);
368     scilab_fill_add(UInt16, ScalarInt8, M_S, UInt16, Int8, UInt16);
369     scilab_fill_add(UInt16, ScalarUInt8, M_S, UInt16, UInt8, UInt16);
370     scilab_fill_add(UInt16, ScalarInt16, M_S, UInt16, Int16, UInt16);
371     scilab_fill_add(UInt16, ScalarUInt16, M_S, UInt16, UInt16, UInt16);
372     scilab_fill_add(UInt16, ScalarInt32, M_S, UInt16, Int32, UInt32);
373     scilab_fill_add(UInt16, ScalarUInt32, M_S, UInt16, UInt32, UInt32);
374     scilab_fill_add(UInt16, ScalarInt64, M_S, UInt16, Int64, UInt64);
375     scilab_fill_add(UInt16, ScalarUInt64, M_S, UInt16, UInt64, UInt64);
376     scilab_fill_add(UInt16, ScalarBool, M_S, UInt16, Bool, UInt16);
377
378     //Scalar + Matrix
379     scilab_fill_add(ScalarUInt16, Double, S_M, UInt16, Double, UInt16);
380     scilab_fill_add(ScalarUInt16, Int8, S_M, UInt16, Int8, UInt16);
381     scilab_fill_add(ScalarUInt16, UInt8, S_M, UInt16, UInt8, UInt16);
382     scilab_fill_add(ScalarUInt16, Int16, S_M, UInt16, Int16, UInt16);
383     scilab_fill_add(ScalarUInt16, UInt16, S_M, UInt16, UInt16, UInt16);
384     scilab_fill_add(ScalarUInt16, Int32, S_M, UInt16, Int32, UInt32);
385     scilab_fill_add(ScalarUInt16, UInt32, S_M, UInt16, UInt32, UInt32);
386     scilab_fill_add(ScalarUInt16, Int64, S_M, UInt16, Int64, UInt64);
387     scilab_fill_add(ScalarUInt16, UInt64, S_M, UInt16, UInt64, UInt64);
388     scilab_fill_add(ScalarUInt16, Bool, S_M, UInt16, Bool, UInt16);
389     scilab_fill_add(ScalarUInt16, Empty, S_E, UInt16, Double, UInt16);
390
391     //Scalar + Scalar
392     scilab_fill_add(ScalarUInt16, ScalarDouble, S_S, UInt16, Double, UInt16);
393     scilab_fill_add(ScalarUInt16, ScalarInt8, S_S, UInt16, Int8, UInt16);
394     scilab_fill_add(ScalarUInt16, ScalarUInt8, S_S, UInt16, UInt8, UInt16);
395     scilab_fill_add(ScalarUInt16, ScalarInt16, S_S, UInt16, Int16, UInt16);
396     scilab_fill_add(ScalarUInt16, ScalarUInt16, S_S, UInt16, UInt16, UInt16);
397     scilab_fill_add(ScalarUInt16, ScalarInt32, S_S, UInt16, Int32, UInt32);
398     scilab_fill_add(ScalarUInt16, ScalarUInt32, S_S, UInt16, UInt32, UInt32);
399     scilab_fill_add(ScalarUInt16, ScalarInt64, S_S, UInt16, Int64, UInt64);
400     scilab_fill_add(ScalarUInt16, ScalarUInt64, S_S, UInt16, UInt64, UInt64);
401     scilab_fill_add(ScalarUInt16, ScalarBool, S_S, UInt16, Bool, UInt16);
402
403     //Int32
404     //Matrix + Matrix
405     scilab_fill_add(Int32, Double, M_M, Int32, Double, Int32);
406     scilab_fill_add(Int32, Int8, M_M, Int32, Int8, Int32);
407     scilab_fill_add(Int32, UInt8, M_M, Int32, UInt8, UInt32);
408     scilab_fill_add(Int32, Int16, M_M, Int32, Int16, Int32);
409     scilab_fill_add(Int32, UInt16, M_M, Int32, UInt16, UInt32);
410     scilab_fill_add(Int32, Int32, M_M, Int32, Int32, Int32);
411     scilab_fill_add(Int32, UInt32, M_M, Int32, UInt32, UInt32);
412     scilab_fill_add(Int32, Int64, M_M, Int32, Int64, Int64);
413     scilab_fill_add(Int32, UInt64, M_M, Int32, UInt64, UInt64);
414     scilab_fill_add(Int32, Bool, M_M, Int32, Bool, Int32);
415     scilab_fill_add(Int32, Empty, M_E, Int32, Double, Int32);
416
417     //Matrix + Scalar
418     scilab_fill_add(Int32, ScalarDouble, M_S, Int32, Double, Int32);
419     scilab_fill_add(Int32, ScalarInt8, M_S, Int32, Int8, Int32);
420     scilab_fill_add(Int32, ScalarUInt8, M_S, Int32, UInt8, UInt32);
421     scilab_fill_add(Int32, ScalarInt16, M_S, Int32, Int16, Int32);
422     scilab_fill_add(Int32, ScalarUInt16, M_S, Int32, UInt16, UInt32);
423     scilab_fill_add(Int32, ScalarInt32, M_S, Int32, Int32, Int32);
424     scilab_fill_add(Int32, ScalarUInt32, M_S, Int32, UInt32, UInt32);
425     scilab_fill_add(Int32, ScalarInt64, M_S, Int32, Int64, Int64);
426     scilab_fill_add(Int32, ScalarUInt64, M_S, Int32, UInt64, UInt64);
427     scilab_fill_add(Int32, ScalarBool, M_S, Int32, Bool, Int32);
428
429     //Scalar + Matrix
430     scilab_fill_add(ScalarInt32, Double, S_M, Int32, Double, Int32);
431     scilab_fill_add(ScalarInt32, Int8, S_M, Int32, Int8, Int32);
432     scilab_fill_add(ScalarInt32, UInt8, S_M, Int32, UInt8, UInt32);
433     scilab_fill_add(ScalarInt32, Int16, S_M, Int32, Int16, Int32);
434     scilab_fill_add(ScalarInt32, UInt16, S_M, Int32, UInt16, UInt32);
435     scilab_fill_add(ScalarInt32, Int32, S_M, Int32, Int32, Int32);
436     scilab_fill_add(ScalarInt32, UInt32, S_M, Int32, UInt32, UInt32);
437     scilab_fill_add(ScalarInt32, Int64, S_M, Int32, Int64, Int64);
438     scilab_fill_add(ScalarInt32, UInt64, S_M, Int32, UInt64, UInt64);
439     scilab_fill_add(ScalarInt32, Bool, S_M, Int32, Bool, Int32);
440     scilab_fill_add(ScalarInt32, Empty, S_E, Int32, Double, Int32);
441
442     //Scalar + Scalar
443     scilab_fill_add(ScalarInt32, ScalarDouble, S_S, Int32, Double, Int32);
444     scilab_fill_add(ScalarInt32, ScalarInt8, S_S, Int32, Int8, Int32);
445     scilab_fill_add(ScalarInt32, ScalarUInt8, S_S, Int32, UInt8, UInt32);
446     scilab_fill_add(ScalarInt32, ScalarInt16, S_S, Int32, Int16, Int32);
447     scilab_fill_add(ScalarInt32, ScalarUInt16, S_S, Int32, UInt16, UInt32);
448     scilab_fill_add(ScalarInt32, ScalarInt32, S_S, Int32, Int32, Int32);
449     scilab_fill_add(ScalarInt32, ScalarUInt32, S_S, Int32, UInt32, UInt32);
450     scilab_fill_add(ScalarInt32, ScalarInt64, S_S, Int32, Int64, Int64);
451     scilab_fill_add(ScalarInt32, ScalarUInt64, S_S, Int32, UInt64, UInt64);
452     scilab_fill_add(ScalarInt32, ScalarBool, S_S, Int32, Bool, Int32);
453
454     //UInt32
455     //Matrix + Matrix
456     scilab_fill_add(UInt32, Double, M_M, UInt32, Double, UInt32);
457     scilab_fill_add(UInt32, Int8, M_M, UInt32, Int8, UInt32);
458     scilab_fill_add(UInt32, UInt8, M_M, UInt32, UInt8, UInt32);
459     scilab_fill_add(UInt32, Int16, M_M, UInt32, Int16, UInt32);
460     scilab_fill_add(UInt32, UInt16, M_M, UInt32, UInt16, UInt32);
461     scilab_fill_add(UInt32, Int32, M_M, UInt32, Int32, UInt32);
462     scilab_fill_add(UInt32, UInt32, M_M, UInt32, UInt32, UInt32);
463     scilab_fill_add(UInt32, Int64, M_M, UInt32, Int64, UInt64);
464     scilab_fill_add(UInt32, UInt64, M_M, UInt32, UInt64, UInt64);
465     scilab_fill_add(UInt32, Bool, M_M, UInt32, Bool, UInt32);
466     scilab_fill_add(UInt32, Empty, M_E, UInt32, Double, UInt32);
467
468     //Matrix + Scalar
469     scilab_fill_add(UInt32, ScalarDouble, M_S, UInt32, Double, UInt32);
470     scilab_fill_add(UInt32, ScalarInt8, M_S, UInt32, Int8, UInt32);
471     scilab_fill_add(UInt32, ScalarUInt8, M_S, UInt32, UInt8, UInt32);
472     scilab_fill_add(UInt32, ScalarInt16, M_S, UInt32, Int16, UInt32);
473     scilab_fill_add(UInt32, ScalarUInt16, M_S, UInt32, UInt16, UInt32);
474     scilab_fill_add(UInt32, ScalarInt32, M_S, UInt32, Int32, UInt32);
475     scilab_fill_add(UInt32, ScalarUInt32, M_S, UInt32, UInt32, UInt32);
476     scilab_fill_add(UInt32, ScalarInt64, M_S, UInt32, Int64, UInt64);
477     scilab_fill_add(UInt32, ScalarUInt64, M_S, UInt32, UInt64, UInt64);
478     scilab_fill_add(UInt32, ScalarBool, M_S, UInt32, Bool, UInt32);
479
480     //Scalar + Matrix
481     scilab_fill_add(ScalarUInt32, Double, S_M, UInt32, Double, UInt32);
482     scilab_fill_add(ScalarUInt32, Int8, S_M, UInt32, Int8, UInt32);
483     scilab_fill_add(ScalarUInt32, UInt8, S_M, UInt32, UInt8, UInt32);
484     scilab_fill_add(ScalarUInt32, Int16, S_M, UInt32, Int16, UInt32);
485     scilab_fill_add(ScalarUInt32, UInt16, S_M, UInt32, UInt16, UInt32);
486     scilab_fill_add(ScalarUInt32, Int32, S_M, UInt32, Int32, UInt32);
487     scilab_fill_add(ScalarUInt32, UInt32, S_M, UInt32, UInt32, UInt32);
488     scilab_fill_add(ScalarUInt32, Int64, S_M, UInt32, Int64, UInt64);
489     scilab_fill_add(ScalarUInt32, UInt64, S_M, UInt32, UInt64, UInt64);
490     scilab_fill_add(ScalarUInt32, Bool, S_M, UInt32, Bool, UInt32);
491     scilab_fill_add(ScalarUInt32, Empty, S_E, UInt32, Double, UInt32);
492
493     //Scalar + Scalar
494     scilab_fill_add(ScalarUInt32, ScalarDouble, S_S, UInt32, Double, UInt32);
495     scilab_fill_add(ScalarUInt32, ScalarInt8, S_S, UInt32, Int8, UInt32);
496     scilab_fill_add(ScalarUInt32, ScalarUInt8, S_S, UInt32, UInt8, UInt32);
497     scilab_fill_add(ScalarUInt32, ScalarInt16, S_S, UInt32, Int16, UInt32);
498     scilab_fill_add(ScalarUInt32, ScalarUInt16, S_S, UInt32, UInt16, UInt32);
499     scilab_fill_add(ScalarUInt32, ScalarInt32, S_S, UInt32, Int32, UInt32);
500     scilab_fill_add(ScalarUInt32, ScalarUInt32, S_S, UInt32, UInt32, UInt32);
501     scilab_fill_add(ScalarUInt32, ScalarInt64, S_S, UInt32, Int64, UInt64);
502     scilab_fill_add(ScalarUInt32, ScalarUInt64, S_S, UInt32, UInt64, UInt64);
503     scilab_fill_add(ScalarUInt32, ScalarBool, S_S, UInt32, Bool, UInt32);
504
505     //Int64
506     //Matrix + Matrix
507     scilab_fill_add(Int64, Double, M_M, Int64, Double, Int64);
508     scilab_fill_add(Int64, Int8, M_M, Int64, Int8, Int64);
509     scilab_fill_add(Int64, UInt8, M_M, Int64, UInt8, UInt64);
510     scilab_fill_add(Int64, Int16, M_M, Int64, Int16, Int64);
511     scilab_fill_add(Int64, UInt16, M_M, Int64, UInt16, UInt64);
512     scilab_fill_add(Int64, Int32, M_M, Int64, Int32, Int64);
513     scilab_fill_add(Int64, UInt32, M_M, Int64, UInt32, UInt64);
514     scilab_fill_add(Int64, Int64, M_M, Int64, Int64, Int64);
515     scilab_fill_add(Int64, UInt64, M_M, Int64, UInt64, UInt64);
516     scilab_fill_add(Int64, Bool, M_M, Int64, Bool, Int64);
517     scilab_fill_add(Int64, Empty, M_E, Int64, Double, Int64);
518
519     //Matrix + Scalar
520     scilab_fill_add(Int64, ScalarDouble, M_S, Int64, Double, Int64);
521     scilab_fill_add(Int64, ScalarInt8, M_S, Int64, Int8, Int64);
522     scilab_fill_add(Int64, ScalarUInt8, M_S, Int64, UInt8, UInt64);
523     scilab_fill_add(Int64, ScalarInt16, M_S, Int64, Int16, Int64);
524     scilab_fill_add(Int64, ScalarUInt16, M_S, Int64, UInt16, UInt64);
525     scilab_fill_add(Int64, ScalarInt32, M_S, Int64, Int32, Int64);
526     scilab_fill_add(Int64, ScalarUInt32, M_S, Int64, UInt32, UInt64);
527     scilab_fill_add(Int64, ScalarInt64, M_S, Int64, Int64, Int64);
528     scilab_fill_add(Int64, ScalarUInt64, M_S, Int64, UInt64, UInt64);
529     scilab_fill_add(Int64, ScalarBool, M_S, Int64, Bool, Int64);
530
531     //Scalar + Matrix
532     scilab_fill_add(ScalarInt64, Double, S_M, Int64, Double, Int64);
533     scilab_fill_add(ScalarInt64, Int8, S_M, Int64, Int8, Int64);
534     scilab_fill_add(ScalarInt64, UInt8, S_M, Int64, UInt8, UInt64);
535     scilab_fill_add(ScalarInt64, Int16, S_M, Int64, Int16, Int64);
536     scilab_fill_add(ScalarInt64, UInt16, S_M, Int64, UInt16, UInt64);
537     scilab_fill_add(ScalarInt64, Int32, S_M, Int64, Int32, Int64);
538     scilab_fill_add(ScalarInt64, UInt32, S_M, Int64, UInt32, UInt64);
539     scilab_fill_add(ScalarInt64, Int64, S_M, Int64, Int64, Int64);
540     scilab_fill_add(ScalarInt64, UInt64, S_M, Int64, UInt64, UInt64);
541     scilab_fill_add(ScalarInt64, Bool, S_M, Int64, Bool, Int64);
542     scilab_fill_add(ScalarInt64, Empty, S_E, Int64, Double, Int64);
543
544     //Scalar + Scalar
545     scilab_fill_add(ScalarInt64, ScalarDouble, S_S, Int64, Double, Int64);
546     scilab_fill_add(ScalarInt64, ScalarInt8, S_S, Int64, Int8, Int64);
547     scilab_fill_add(ScalarInt64, ScalarUInt8, S_S, Int64, UInt8, UInt64);
548     scilab_fill_add(ScalarInt64, ScalarInt16, S_S, Int64, Int16, Int64);
549     scilab_fill_add(ScalarInt64, ScalarUInt16, S_S, Int64, UInt16, UInt64);
550     scilab_fill_add(ScalarInt64, ScalarInt32, S_S, Int64, Int32, Int64);
551     scilab_fill_add(ScalarInt64, ScalarUInt32, S_S, Int64, UInt32, UInt64);
552     scilab_fill_add(ScalarInt64, ScalarInt64, S_S, Int64, Int64, Int64);
553     scilab_fill_add(ScalarInt64, ScalarUInt64, S_S, Int64, UInt64, UInt64);
554     scilab_fill_add(ScalarInt64, ScalarBool, S_S, Int64, Bool, Int64);
555
556     //UInt64
557     //Matrix + Matrix
558     scilab_fill_add(UInt64, Double, M_M, UInt64, Double, UInt64);
559     scilab_fill_add(UInt64, Int8, M_M, UInt64, Int8, UInt64);
560     scilab_fill_add(UInt64, UInt8, M_M, UInt64, UInt8, UInt64);
561     scilab_fill_add(UInt64, Int16, M_M, UInt64, Int16, UInt64);
562     scilab_fill_add(UInt64, UInt16, M_M, UInt64, UInt16, UInt64);
563     scilab_fill_add(UInt64, Int32, M_M, UInt64, Int32, UInt64);
564     scilab_fill_add(UInt64, UInt32, M_M, UInt64, UInt32, UInt64);
565     scilab_fill_add(UInt64, Int64, M_M, UInt64, Int64, UInt64);
566     scilab_fill_add(UInt64, UInt64, M_M, UInt64, UInt64, UInt64);
567     scilab_fill_add(UInt64, Bool, M_M, UInt64, Bool, UInt64);
568     scilab_fill_add(UInt64, Empty, M_E, UInt64, Double, UInt64);
569
570     //Matrix + Scalar
571     scilab_fill_add(UInt64, ScalarDouble, M_S, UInt64, Double, UInt64);
572     scilab_fill_add(UInt64, ScalarInt8, M_S, UInt64, Int8, UInt64);
573     scilab_fill_add(UInt64, ScalarUInt8, M_S, UInt64, UInt8, UInt64);
574     scilab_fill_add(UInt64, ScalarInt16, M_S, UInt64, Int16, UInt64);
575     scilab_fill_add(UInt64, ScalarUInt16, M_S, UInt64, UInt16, UInt64);
576     scilab_fill_add(UInt64, ScalarInt32, M_S, UInt64, Int32, UInt64);
577     scilab_fill_add(UInt64, ScalarUInt32, M_S, UInt64, UInt32, UInt64);
578     scilab_fill_add(UInt64, ScalarInt64, M_S, UInt64, Int64, UInt64);
579     scilab_fill_add(UInt64, ScalarUInt64, M_S, UInt64, UInt64, UInt64);
580     scilab_fill_add(UInt64, ScalarBool, M_S, UInt64, Bool, UInt64);
581
582     //Scalar + Matrix
583     scilab_fill_add(ScalarUInt64, Double, S_M, UInt64, Double, UInt64);
584     scilab_fill_add(ScalarUInt64, Int8, S_M, UInt64, Int8, UInt64);
585     scilab_fill_add(ScalarUInt64, UInt8, S_M, UInt64, UInt8, UInt64);
586     scilab_fill_add(ScalarUInt64, Int16, S_M, UInt64, Int16, UInt64);
587     scilab_fill_add(ScalarUInt64, UInt16, S_M, UInt64, UInt16, UInt64);
588     scilab_fill_add(ScalarUInt64, Int32, S_M, UInt64, Int32, UInt64);
589     scilab_fill_add(ScalarUInt64, UInt32, S_M, UInt64, UInt32, UInt64);
590     scilab_fill_add(ScalarUInt64, Int64, S_M, UInt64, Int64, UInt64);
591     scilab_fill_add(ScalarUInt64, UInt64, S_M, UInt64, UInt64, UInt64);
592     scilab_fill_add(ScalarUInt64, Bool, S_M, UInt64, Bool, UInt64);
593     scilab_fill_add(ScalarUInt64, Empty, S_E, UInt64, Double, UInt64);
594
595     //Scalar + Scalar
596     scilab_fill_add(ScalarUInt64, ScalarDouble, S_S, UInt64, Double, UInt64);
597     scilab_fill_add(ScalarUInt64, ScalarInt8, S_S, UInt64, Int8, UInt64);
598     scilab_fill_add(ScalarUInt64, ScalarUInt8, S_S, UInt64, UInt8, UInt64);
599     scilab_fill_add(ScalarUInt64, ScalarInt16, S_S, UInt64, Int16, UInt64);
600     scilab_fill_add(ScalarUInt64, ScalarUInt16, S_S, UInt64, UInt16, UInt64);
601     scilab_fill_add(ScalarUInt64, ScalarInt32, S_S, UInt64, Int32, UInt64);
602     scilab_fill_add(ScalarUInt64, ScalarUInt32, S_S, UInt64, UInt32, UInt64);
603     scilab_fill_add(ScalarUInt64, ScalarInt64, S_S, UInt64, Int64, UInt64);
604     scilab_fill_add(ScalarUInt64, ScalarUInt64, S_S, UInt64, UInt64, UInt64);
605     scilab_fill_add(ScalarUInt64, ScalarBool, S_S, UInt64, Bool, UInt64);
606
607     //Bool
608     //Matrix + Matrix
609     scilab_fill_add(Bool, Double, M_M, Bool, Double, Double);
610     scilab_fill_add(Bool, Int8, M_M, Bool, Int8, Int8);
611     scilab_fill_add(Bool, UInt8, M_M, Bool, UInt8, UInt8);
612     scilab_fill_add(Bool, Int16, M_M, Bool, Int16, Int16);
613     scilab_fill_add(Bool, UInt16, M_M, Bool, UInt16, UInt16);
614     scilab_fill_add(Bool, Int32, M_M, Bool, Int32, Int32);
615     scilab_fill_add(Bool, UInt32, M_M, Bool, UInt32, UInt32);
616     scilab_fill_add(Bool, Int64, M_M, Bool, Int64, Int64);
617     scilab_fill_add(Bool, UInt64, M_M, Bool, UInt64, UInt64);
618     scilab_fill_add(Bool, Bool, M_M, Bool, Bool, Bool);
619     scilab_fill_add(Bool, Empty, M_E, Bool, Double, Double);
620
621     //Matrix + Scalar
622     scilab_fill_add(Bool, ScalarDouble, M_S, Bool, Double, Double);
623     scilab_fill_add(Bool, ScalarInt8, M_S, Bool, Int8, Int8);
624     scilab_fill_add(Bool, ScalarUInt8, M_S, Bool, UInt8, UInt8);
625     scilab_fill_add(Bool, ScalarInt16, M_S, Bool, Int16, Int16);
626     scilab_fill_add(Bool, ScalarUInt16, M_S, Bool, UInt16, UInt16);
627     scilab_fill_add(Bool, ScalarInt32, M_S, Bool, Int32, Int32);
628     scilab_fill_add(Bool, ScalarUInt32, M_S, Bool, UInt32, UInt32);
629     scilab_fill_add(Bool, ScalarInt64, M_S, Bool, Int64, Int64);
630     scilab_fill_add(Bool, ScalarUInt64, M_S, Bool, UInt64, UInt64);
631     scilab_fill_add(Bool, ScalarBool, M_S, Bool, Bool, Bool);
632
633     //Scalar + Matrix
634     scilab_fill_add(ScalarBool, Double, S_M, Bool, Double, Double);
635     scilab_fill_add(ScalarBool, Int8, S_M, Bool, Int8, Int8);
636     scilab_fill_add(ScalarBool, UInt8, S_M, Bool, UInt8, UInt8);
637     scilab_fill_add(ScalarBool, Int16, S_M, Bool, Int16, Int16);
638     scilab_fill_add(ScalarBool, UInt16, S_M, Bool, UInt16, UInt16);
639     scilab_fill_add(ScalarBool, Int32, S_M, Bool, Int32, Int32);
640     scilab_fill_add(ScalarBool, UInt32, S_M, Bool, UInt32, UInt32);
641     scilab_fill_add(ScalarBool, Int64, S_M, Bool, Int64, Int64);
642     scilab_fill_add(ScalarBool, UInt64, S_M, Bool, UInt64, UInt64);
643     scilab_fill_add(ScalarBool, Bool, S_M, Bool, Bool, Bool);
644     scilab_fill_add(ScalarBool, Empty, S_E, Bool, Double, Double);
645
646     //Scalar + Scalar
647     scilab_fill_add(ScalarBool, ScalarDouble, S_S, Bool, Double, Double);
648     scilab_fill_add(ScalarBool, ScalarInt8, S_S, Bool, Int8, Int8);
649     scilab_fill_add(ScalarBool, ScalarUInt8, S_S, Bool, UInt8, UInt8);
650     scilab_fill_add(ScalarBool, ScalarInt16, S_S, Bool, Int16, Int16);
651     scilab_fill_add(ScalarBool, ScalarUInt16, S_S, Bool, UInt16, UInt16);
652     scilab_fill_add(ScalarBool, ScalarInt32, S_S, Bool, Int32, Int32);
653     scilab_fill_add(ScalarBool, ScalarUInt32, S_S, Bool, UInt32, UInt32);
654     scilab_fill_add(ScalarBool, ScalarInt64, S_S, Bool, Int64, Int64);
655     scilab_fill_add(ScalarBool, ScalarUInt64, S_S, Bool, UInt64, UInt64);
656     scilab_fill_add(ScalarBool, ScalarBool, S_S, Bool, Bool, Bool);
657
658     //String
659     scilab_fill_add(String, String, M_M, String, String, String);
660     scilab_fill_add(String, ScalarString, M_S, String, String, String);
661     scilab_fill_add(String, Empty, M_E, String, Double, String);
662
663     scilab_fill_add(ScalarString, String, S_M, String, String, String);
664     scilab_fill_add(ScalarString, ScalarString, S_S, String, String, String);
665     scilab_fill_add(ScalarString, Empty, S_E, String, Double, String);
666
667     //Identity
668     scilab_fill_add(Identity, Double, I_M, Double, Double, Double);
669     scilab_fill_add(Identity, DoubleComplex, I_MC, Double, Double, Double);
670     scilab_fill_add(Identity, ScalarDouble, I_S, Double, Double, Double);
671     scilab_fill_add(Identity, ScalarDoubleComplex, I_SC, Double, Double, Double);
672     scilab_fill_add(Identity, Identity, I_I, Double, Double, Double);
673     scilab_fill_add(Identity, IdentityComplex, I_IC, Double, Double, Double);
674     scilab_fill_add(Identity, Empty, I_E, Double, Double, Double);
675
676     scilab_fill_add(Identity, Polynom, I_M, Double, Polynom, Polynom);
677     scilab_fill_add(Identity, PolynomComplex, I_M, Double, Polynom, Polynom);
678     scilab_fill_add(Identity, ScalarPolynom, I_M, Double, Polynom, Polynom);
679     scilab_fill_add(Identity, ScalarPolynomComplex, I_M, Double, Polynom, Polynom);
680     scilab_fill_add(Identity, Sparse, M_M, Double, Sparse, Sparse);
681     scilab_fill_add(Identity, SparseComplex, M_M, Double, Sparse, Sparse);
682
683     scilab_fill_add(IdentityComplex, Double, IC_M, Double, Double, Double);
684     scilab_fill_add(IdentityComplex, DoubleComplex, IC_MC, Double, Double, Double);
685     scilab_fill_add(IdentityComplex, ScalarDouble, IC_S, Double, Double, Double);
686     scilab_fill_add(IdentityComplex, ScalarDoubleComplex, IC_SC, Double, Double, Double);
687     scilab_fill_add(IdentityComplex, Identity, IC_I, Double, Double, Double);
688     scilab_fill_add(IdentityComplex, IdentityComplex, IC_IC, Double, Double, Double);
689     scilab_fill_add(IdentityComplex, Empty, IC_E, Double, Double, Double);
690
691     scilab_fill_add(IdentityComplex, Polynom, I_M, Double, Polynom, Polynom);
692     scilab_fill_add(IdentityComplex, PolynomComplex, I_M, Double, Polynom, Polynom);
693     scilab_fill_add(IdentityComplex, ScalarPolynom, I_M, Double, Polynom, Polynom);
694     scilab_fill_add(IdentityComplex, ScalarPolynomComplex, I_M, Double, Polynom, Polynom);
695     scilab_fill_add(IdentityComplex, Sparse, M_M, Double, Sparse, Sparse);
696     scilab_fill_add(IdentityComplex, SparseComplex, M_M, Double, Sparse, Sparse);
697
698     //Polynom
699
700     //poly + poly
701     scilab_fill_add(Polynom, Polynom, M_M, Polynom, Polynom, Polynom);
702     scilab_fill_add(Polynom, PolynomComplex, M_M, Polynom, Polynom, Polynom);
703     scilab_fill_add(PolynomComplex, Polynom, M_M, Polynom, Polynom, Polynom);
704     scilab_fill_add(PolynomComplex, PolynomComplex, M_M, Polynom, Polynom, Polynom);
705
706     //poly + scalar poly
707     scilab_fill_add(Polynom, ScalarPolynom, M_M, Polynom, Polynom, Polynom);
708     scilab_fill_add(Polynom, ScalarPolynomComplex, M_M, Polynom, Polynom, Polynom);
709     scilab_fill_add(PolynomComplex, ScalarPolynom, M_M, Polynom, Polynom, Polynom);
710     scilab_fill_add(PolynomComplex, ScalarPolynomComplex, M_M, Polynom, Polynom, Polynom);
711
712     //poly + double
713     scilab_fill_add(Polynom, Double, M_M, Polynom, Double, Polynom);
714     scilab_fill_add(Polynom, DoubleComplex, M_M, Polynom, Double, Polynom);
715     scilab_fill_add(PolynomComplex, Double, M_M, Polynom, Double, Polynom);
716     scilab_fill_add(PolynomComplex, DoubleComplex, M_M, Polynom, Double, Polynom);
717
718     //poly + scalar double
719     scilab_fill_add(Polynom, ScalarDouble, M_M, Polynom, Double, Polynom);
720     scilab_fill_add(Polynom, ScalarDoubleComplex, M_M, Polynom, Double, Polynom);
721     scilab_fill_add(PolynomComplex, ScalarDouble, M_M, Polynom, Double, Polynom);
722     scilab_fill_add(PolynomComplex, ScalarDoubleComplex, M_M, Polynom, Double, Polynom);
723
724     //poly + []
725     scilab_fill_add(Polynom, Empty, M_E, Polynom, Double, Polynom);
726     scilab_fill_add(PolynomComplex, Empty, M_E, Polynom, Double, Polynom);
727
728     //poly + eye
729     scilab_fill_add(Polynom, Identity, M_I, Polynom, Double, Polynom);
730     scilab_fill_add(Polynom, IdentityComplex, M_I, Polynom, Double, Polynom);
731     scilab_fill_add(PolynomComplex, Identity, M_I, Polynom, Double, Polynom);
732     scilab_fill_add(PolynomComplex, IdentityComplex, M_I, Polynom, Double, Polynom);
733
734     //scalar poly + poly
735     scilab_fill_add(ScalarPolynom, Polynom, M_M, Polynom, Polynom, Polynom);
736     scilab_fill_add(ScalarPolynom, PolynomComplex, M_M, Polynom, Polynom, Polynom);
737     scilab_fill_add(ScalarPolynomComplex, Polynom, M_M, Polynom, Polynom, Polynom);
738     scilab_fill_add(ScalarPolynomComplex, PolynomComplex, M_M, Polynom, Polynom, Polynom);
739
740     //scalar poly + scalar poly
741     scilab_fill_add(ScalarPolynom, ScalarPolynom, M_M, Polynom, Polynom, Polynom);
742     scilab_fill_add(ScalarPolynom, ScalarPolynomComplex, M_M, Polynom, Polynom, Polynom);
743     scilab_fill_add(ScalarPolynomComplex, ScalarPolynom, M_M, Polynom, Polynom, Polynom);
744     scilab_fill_add(ScalarPolynomComplex, ScalarPolynomComplex, M_M, Polynom, Polynom, Polynom);
745
746     //scalar poly + double
747     scilab_fill_add(ScalarPolynom, Double, M_M, Polynom, Double, Polynom);
748     scilab_fill_add(ScalarPolynom, DoubleComplex, M_M, Polynom, Double, Polynom);
749     scilab_fill_add(ScalarPolynomComplex, Double, M_M, Polynom, Double, Polynom);
750     scilab_fill_add(ScalarPolynomComplex, DoubleComplex, M_M, Polynom, Double, Polynom);
751
752     //scalar poly + scalar double
753     scilab_fill_add(ScalarPolynom, ScalarDouble, M_M, Polynom, Double, Polynom);
754     scilab_fill_add(ScalarPolynom, ScalarDoubleComplex, M_M, Polynom, Double, Polynom);
755     scilab_fill_add(ScalarPolynomComplex, ScalarDouble, M_M, Polynom, Double, Polynom);
756     scilab_fill_add(ScalarPolynomComplex, ScalarDoubleComplex, M_M, Polynom, Double, Polynom);
757
758     //scalar poly + []
759     scilab_fill_add(ScalarPolynom, Empty, M_E, Polynom, Double, Polynom);
760     scilab_fill_add(ScalarPolynomComplex, Empty, M_E, Polynom, Double, Polynom);
761
762     //scalar poly + eye
763     scilab_fill_add(ScalarPolynom, Identity, M_I, Polynom, Double, Polynom);
764     scilab_fill_add(ScalarPolynom, IdentityComplex, M_I, Polynom, Double, Polynom);
765     scilab_fill_add(ScalarPolynomComplex, Identity, M_I, Polynom, Double, Polynom);
766     scilab_fill_add(ScalarPolynomComplex, IdentityComplex, M_I, Polynom, Double, Polynom);
767
768     //Sparse
769     scilab_fill_add(Sparse, Sparse, M_M, Sparse, Sparse, Sparse);
770     scilab_fill_add(Sparse, SparseComplex, M_M, Sparse, Sparse, Sparse);
771     scilab_fill_add(Sparse, Double, M_M, Sparse, Double, Double);
772     scilab_fill_add(Sparse, DoubleComplex, M_M, Sparse, Double, Double);
773     scilab_fill_add(Sparse, ScalarDouble, M_M, Sparse, Double, Double);
774     scilab_fill_add(Sparse, ScalarDoubleComplex, M_M, Sparse, Double, Double);
775
776     scilab_fill_add(Sparse, Empty, M_E, Sparse, Double, Sparse);
777     scilab_fill_add(Sparse, Identity, M_M, Sparse, Double, Sparse);
778     scilab_fill_add(Sparse, IdentityComplex, M_M, Sparse, Double, Sparse);
779
780     scilab_fill_add(SparseComplex, Sparse, M_M, Sparse, Sparse, Sparse);
781     scilab_fill_add(SparseComplex, SparseComplex, M_M, Sparse, Sparse, Sparse);
782     scilab_fill_add(SparseComplex, Double, M_M, Sparse, Double, Double);
783     scilab_fill_add(SparseComplex, DoubleComplex, M_M, Sparse, Double, Double);
784     scilab_fill_add(SparseComplex, ScalarDouble, M_M, Sparse, Double, Double);
785     scilab_fill_add(SparseComplex, ScalarDoubleComplex, M_M, Sparse, Double, Double);
786
787     scilab_fill_add(SparseComplex, Empty, M_E, Sparse, Double, Sparse);
788     scilab_fill_add(SparseComplex, Identity, M_M, Sparse, Double, Sparse);
789     scilab_fill_add(SparseComplex, IdentityComplex, M_M, Sparse, Double, Sparse);
790
791 #undef scilab_fill_add
792 }
793
794 InternalType *GenericPlus(InternalType *_pLeftOperand, InternalType *_pRightOperand)
795 {
796     InternalType *pResult = NULL;
797
798     add_function add = pAddfunction[_pLeftOperand->getId()][_pRightOperand->getId()];
799     if (add)
800     {
801         pResult = add(_pLeftOperand, _pRightOperand);
802         if (pResult)
803         {
804             return pResult;
805         }
806     }
807
808     /*
809     ** Default case : Return NULL will Call Overloading.
810     */
811     return NULL;
812 }
813
814 int AddSparseToSparse(Sparse* sp1, Sparse* sp2, Sparse** pSpRes)
815 {
816     //check scalar hidden in a sparse ;)
817     if (sp1->getRows() == 1 && sp1->getCols() == 1)
818     {
819         //do scalar + sp
820         Double* pDbl = NULL;
821         if (sp1->isComplex())
822         {
823             std::complex<double> dbl = sp1->getImg(0, 0);
824             pDbl = new Double(dbl.real(), dbl.imag());
825         }
826         else
827         {
828             pDbl = new Double(sp1->get(0, 0));
829         }
830
831         AddSparseToDouble(sp2, pDbl, (GenericType**)pSpRes);
832         delete pDbl;
833         return 0;
834     }
835
836     if (sp2->getRows() == 1 && sp2->getCols() == 1)
837     {
838         //do sp + scalar
839         Double* pDbl = NULL;
840         if (sp2->isComplex())
841         {
842             std::complex<double> dbl = sp2->getImg(0, 0);
843             pDbl = new Double(dbl.real(), dbl.imag());
844         }
845         else
846         {
847             pDbl = new Double(sp2->get(0, 0));
848         }
849
850         AddSparseToDouble(sp1, pDbl, (GenericType**)pSpRes);
851         delete pDbl;
852         return 0;
853     }
854
855     if (sp1->getRows() != sp2->getRows() || sp1->getCols() != sp2->getCols())
856     {
857         //dimensions not match
858         return 1;
859     }
860
861     if (sp1->nonZeros() == 0)
862     {
863         //sp([]) + sp
864         *pSpRes = new Sparse(*sp2);
865         return 0;
866     }
867
868     if (sp2->nonZeros() == 0)
869     {
870         //sp + sp([])
871         *pSpRes = new Sparse(*sp1);
872         return 0;
873     }
874
875     //copy sp1 in pSpRes
876     *pSpRes = sp1->add(*sp2);
877     return 0;
878 }
879
880 int AddSparseToDouble(Sparse* sp, Double* d, GenericType** pDRes)
881 {
882     int iOne = 1; //fortran
883     bool bComplex1 = sp->isComplex();
884     bool bComplex2 = d->isComplex();
885
886     if (d->isIdentity())
887     {
888         //convert to sp
889         Sparse* pS = new Sparse(sp->getRows(), sp->getCols(), d->isComplex());
890         if (pS->isComplex())
891         {
892             for (int i = 0 ; i < std::min(sp->getRows(), sp->getCols()) ; i++)
893             {
894                 pS->set(i, i, std::complex<double>(d->get(0), d->getImg(0)));
895             }
896         }
897         else
898         {
899             for (int i = 0 ; i < std::min(sp->getRows(), sp->getCols()) ; i++)
900             {
901                 pS->set(i, i, d->get(0));
902             }
903         }
904
905         AddSparseToSparse(sp, pS, (Sparse**)pDRes);
906         delete pS;
907         return 0;
908     }
909
910     if (sp->isScalar() && d->isScalar())
911     {
912         //sp + d
913         Double* pRes = (Double*)d->clone();
914         pRes->setComplex(bComplex1 | bComplex2);
915
916         if (bComplex1)
917         {
918             std::complex<double> dbl = sp->getImg(0, 0);
919             pRes->set(0, pRes->get(0) + dbl.real());
920             pRes->setImg(0, pRes->getImg(0) + dbl.imag());
921         }
922         else
923         {
924             pRes->set(0, pRes->get(0) + sp->getReal(0));
925         }
926
927         *pDRes = pRes;
928         return 0;
929     }
930
931     if (d->isScalar())
932     {
933         //SP + d
934         Double* pRes = new Double(sp->getRows(), sp->getCols(), bComplex1 | bComplex2);
935         int iSize = sp->getSize();
936         double dblVal = d->get(0);
937         C2F(dset)(&iSize, &dblVal, pRes->get(), &iOne);
938         if (bComplex2)
939         {
940             double dblValI = d->getImg(0);
941             C2F(dset)(&iSize, &dblValI, pRes->getImg(), &iOne);
942         }
943         else if (bComplex1)
944         {
945             //initialize imag part at 0
946             double dblValI = 0;
947             C2F(dset)(&iSize, &dblValI, pRes->getImg(), &iOne);
948         }
949
950         int nonZeros = static_cast<int>(sp->nonZeros());
951         int* pRows = new int[nonZeros * 2];
952         sp->outputRowCol(pRows);
953         int* pCols = pRows + nonZeros;
954
955         if (bComplex1)
956         {
957             for (int i = 0 ; i < nonZeros ; i++)
958             {
959                 int iRow = static_cast<int>(pRows[i]) - 1;
960                 int iCol = static_cast<int>(pCols[i]) - 1;
961                 std::complex<double> dbl = sp->getImg(iRow, iCol);
962                 pRes->set(iRow, iCol, pRes->get(iRow, iCol) + dbl.real());
963                 pRes->setImg(iRow, iCol, pRes->getImg(iRow, iCol) + dbl.imag());
964             }
965         }
966         else
967         {
968             for (int i = 0 ; i < nonZeros ; i++)
969             {
970                 int iRow = static_cast<int>(pRows[i]) - 1;
971                 int iCol = static_cast<int>(pCols[i]) - 1;
972                 pRes->set(iRow, iCol, pRes->get(iRow, iCol) + sp->get(iRow, iCol));
973             }
974         }
975         *pDRes = pRes;
976
977         //clear
978         delete[] pRows;
979
980         return 0;
981     }
982
983     if (sp->isScalar())
984     {
985         //sp + D
986         Double* pRes = (Double*)d->clone();
987         pRes->setComplex(bComplex1 | bComplex2);
988
989         if (bComplex1)
990         {
991             double* pReal = pRes->get();
992             double* pImg = pRes->getImg();
993             for (int i = 0 ; i < pRes->getSize() ; i++)
994             {
995                 std::complex<double> dbl = sp->getImg(0, 0);
996                 pReal[i] += dbl.real();
997                 pImg[i] += dbl.imag();
998             }
999         }
1000         else
1001         {
1002             double* pReal = pRes->get();
1003             for (int i = 0 ; i < pRes->getSize() ; i++)
1004             {
1005                 pReal[i] += sp->get(0, 0);
1006             }
1007         }
1008
1009         *pDRes = pRes;
1010         return 0;
1011     }
1012
1013
1014     if (sp->getRows() == d->getRows() && sp->getCols() == d->getCols())
1015     {
1016         //SP + D
1017         Double* pRes = (Double*)d->clone();
1018         pRes->setComplex(bComplex1 | bComplex2);
1019
1020         int nonZeros = static_cast<int>(sp->nonZeros());
1021         int* pRows = new int[nonZeros * 2];
1022         sp->outputRowCol(pRows);
1023         int* pCols = pRows + nonZeros;
1024
1025         if (bComplex1)
1026         {
1027             for (int i = 0 ; i < nonZeros ; i++)
1028             {
1029                 int iRow = static_cast<int>(pRows[i]) - 1;
1030                 int iCol = static_cast<int>(pCols[i]) - 1;
1031                 std::complex<double> dbl = sp->getImg(iRow, iCol);
1032                 pRes->set(iRow, iCol, pRes->get(iRow, iCol) + dbl.real());
1033                 pRes->setImg(iRow, iCol, pRes->getImg(iRow, iCol) + dbl.imag());
1034             }
1035         }
1036         else
1037         {
1038             for (int i = 0 ; i < nonZeros ; i++)
1039             {
1040                 int iRow = static_cast<int>(pRows[i]) - 1;
1041                 int iCol = static_cast<int>(pCols[i]) - 1;
1042                 pRes->set(iRow, iCol, pRes->get(iRow, iCol) + sp->get(iRow, iCol));
1043             }
1044         }
1045
1046         //clear
1047         delete[] pRows;
1048         *pDRes = pRes;
1049         return 0;
1050     }
1051     return 1;
1052 }
1053
1054 int AddDoubleToSparse(Double* d, Sparse* sp, GenericType** pDRes)
1055 {
1056     /* uses commutativity */
1057     return AddSparseToDouble(sp, d, pDRes);
1058 }
1059
1060 template<class T, class U, class O>
1061 InternalType* add_M_M(T *_pL, U *_pR)
1062 {
1063     int iDimsL = _pL->getDims();
1064     int iDimsR = _pR->getDims();
1065
1066     if (iDimsL != iDimsR)
1067     {
1068         return nullptr;
1069     }
1070
1071     int* piDimsL = _pL->getDimsArray();
1072     int* piDimsR = _pR->getDimsArray();
1073
1074     for (int i = 0 ; i < iDimsL ; ++i)
1075     {
1076         if (piDimsL[i] != piDimsR[i])
1077         {
1078             throw ast::InternalError(_W("Inconsistent row/column dimensions.\n"));
1079         }
1080     }
1081
1082     O* pOut = new O(iDimsL, piDimsL);
1083
1084     add(_pL->get(), (size_t)_pL->getSize(), _pR->get(), pOut->get());
1085     return pOut;
1086 }
1087
1088 template<class T, class U, class O>
1089 InternalType* add_M_MC(T *_pL, U *_pR)
1090 {
1091     int iDimsL = _pL->getDims();
1092     int iDimsR = _pR->getDims();
1093
1094     if (iDimsL != iDimsR)
1095     {
1096         return nullptr;
1097     }
1098
1099     int* piDimsL = _pL->getDimsArray();
1100     int* piDimsR = _pR->getDimsArray();
1101
1102     for (int i = 0 ; i < iDimsL ; ++i)
1103     {
1104         if (piDimsL[i] != piDimsR[i])
1105         {
1106             throw ast::InternalError(_W("Inconsistent row/column dimensions.\n"));
1107         }
1108     }
1109
1110     O* pOut = new O(iDimsL, piDimsL, true);
1111
1112     add(_pL->get(), (size_t)_pL->getSize(), _pR->get(), _pR->getImg(), pOut->get(), pOut->getImg());
1113     return pOut;
1114 }
1115
1116 template<class T, class U, class O>
1117 InternalType* add_M_S(T *_pL, U *_pR)
1118 {
1119     O* pOut = new O(_pL->getDims(), _pL->getDimsArray());
1120     add(_pL->get(), (size_t)_pL->getSize(), _pR->get(0), pOut->get());
1121     return pOut;
1122 }
1123
1124 template<class T, class U, class O>
1125 InternalType* add_M_SC(T *_pL, U *_pR)
1126 {
1127     O* pOut = new O(_pL->getDims(), _pL->getDimsArray(), true);
1128     add(_pL->get(), (size_t)_pL->getSize(), _pR->get(0), _pR->getImg(0), pOut->get(), pOut->getImg());
1129     return pOut;
1130 }
1131
1132 template<class T, class U, class O>
1133 InternalType* add_M_E(T *_pL, U * /*_pR*/)
1134 {
1135     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1136     Double* pOut = Double::Empty();
1137     add();
1138     return pOut;
1139 }
1140
1141
1142 template<class T, class U, class O>
1143 InternalType* add_MC_M(T *_pL, U *_pR)
1144 {
1145     return add_M_MC<U, T, O>(_pR, _pL);
1146 }
1147
1148 template<class T, class U, class O>
1149 InternalType* add_MC_MC(T *_pL, U *_pR)
1150 {
1151     int iDimsL = _pL->getDims();
1152     int iDimsR = _pR->getDims();
1153
1154     if (iDimsL != iDimsR)
1155     {
1156         return nullptr;
1157     }
1158
1159     int* piDimsL = _pL->getDimsArray();
1160     int* piDimsR = _pR->getDimsArray();
1161
1162     for (int i = 0 ; i < iDimsL ; ++i)
1163     {
1164         if (piDimsL[i] != piDimsR[i])
1165         {
1166             throw ast::InternalError(_W("Inconsistent row/column dimensions.\n"));
1167         }
1168     }
1169
1170     O* pOut = new O(iDimsL, piDimsL, true);
1171
1172     add(_pL->get(), _pL->getImg(), (size_t)_pL->getSize(), _pR->get(), _pR->getImg(), pOut->get(), pOut->getImg());
1173     return pOut;
1174 }
1175
1176 template<class T, class U, class O>
1177 InternalType* add_MC_S(T *_pL, U *_pR)
1178 {
1179     O* pOut = new O(_pL->getDims(), _pL->getDimsArray(), true);
1180     add(_pL->get(), _pL->getImg(), (size_t)_pL->getSize(), _pR->get(0), pOut->get(), pOut->getImg());
1181     return pOut;
1182 }
1183
1184 template<class T, class U, class O>
1185 InternalType* add_MC_SC(T *_pL, U *_pR)
1186 {
1187     O* pOut = new O(_pL->getDims(), _pL->getDimsArray(), true);
1188     add(_pL->get(), _pL->getImg(), (size_t)_pL->getSize(), _pR->get(0), _pR->getImg(0), pOut->get(), pOut->getImg());
1189     return pOut;
1190 }
1191
1192 template<class T, class U, class O>
1193 InternalType* add_MC_E(T *_pL, U * /*_pR*/)
1194 {
1195     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1196     Double* pOut = Double::Empty();
1197     add();
1198     return pOut;
1199 }
1200
1201
1202 template<class T, class U, class O>
1203 InternalType* add_S_M(T *_pL, U *_pR)
1204 {
1205     return add_M_S<U, T, O>(_pR, _pL);
1206 }
1207
1208 template<class T, class U, class O>
1209 InternalType* add_S_MC(T *_pL, U *_pR)
1210 {
1211     return add_MC_S<U, T, O>(_pR, _pL);
1212 }
1213
1214 template<class T, class U, class O>
1215 InternalType* add_S_S(T *_pL, U *_pR)
1216 {
1217     O* pOut = new O(0);
1218     add(_pL->get(0), _pR->get(0), pOut->get());
1219     return pOut;
1220 }
1221
1222 template<class T, class U, class O>
1223 InternalType* add_S_SC(T *_pL, U *_pR)
1224 {
1225     O* pOut = new O(0.0, 0.0);
1226     add(_pL->get(), 1, _pR->get(0), _pR->getImg(0), pOut->get(), pOut->getImg());
1227     return pOut;
1228 }
1229
1230 template<class T, class U, class O>
1231 InternalType* add_S_E(T *_pL, U * /*_pR*/)
1232 {
1233     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1234     Double* pOut = Double::Empty();
1235     add();
1236     return pOut;
1237 }
1238
1239
1240 template<class T, class U, class O>
1241 InternalType* add_SC_M(T *_pL, U *_pR)
1242 {
1243     return add_M_SC<U, T, O>(_pR, _pL);
1244 }
1245
1246 template<class T, class U, class O>
1247 InternalType* add_SC_MC(T *_pL, U *_pR)
1248 {
1249     return add_MC_SC<U, T, O>(_pR, _pL);
1250 }
1251
1252 template<class T, class U, class O>
1253 InternalType* add_SC_S(T *_pL, U *_pR)
1254 {
1255     return add_S_SC<U, T, O>(_pR, _pL);
1256 }
1257
1258 template<class T, class U, class O>
1259 InternalType* add_SC_SC(T *_pL, U *_pR)
1260 {
1261     O* pOut = new O(0.0, 0.0);
1262     add(_pL->get(0), _pL->getImg(0), _pR->get(0), _pR->getImg(0), pOut->get(), pOut->getImg());
1263     return pOut;
1264 }
1265
1266 template<class T, class U, class O>
1267 InternalType* add_SC_E(T *_pL, U * /*_pR*/)
1268 {
1269     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1270     Double* pOut = Double::Empty();
1271     add();
1272     return pOut;
1273 }
1274
1275
1276 template<class T, class U, class O>
1277 InternalType* add_E_M(T *_pL, U *_pR)
1278 {
1279     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1280     Double* pOut = Double::Empty();
1281     add();
1282     return pOut;
1283 }
1284
1285 template<class T, class U, class O>
1286 InternalType* add_E_MC(T *_pL, U *_pR)
1287 {
1288     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1289     Double* pOut = Double::Empty();
1290     add();
1291     return pOut;
1292 }
1293
1294 template<class T, class U, class O>
1295 InternalType* add_E_S(T *_pL, U *_pR)
1296 {
1297     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1298     Double* pOut = Double::Empty();
1299     add();
1300     return pOut;
1301 }
1302
1303 template<class T, class U, class O>
1304 InternalType* add_E_SC(T *_pL, U *_pR)
1305 {
1306     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1307     Double* pOut = Double::Empty();
1308     add();
1309     return pOut;
1310 }
1311
1312 template<class T, class U, class O>
1313 InternalType* add_E_E(T * /*_pL*/, U * /*_pR*/)
1314 {
1315     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1316     Double* pOut = Double::Empty();
1317     add();
1318     return pOut;
1319 }
1320
1321 template<class T, class U, class O>
1322 InternalType* add_I_M(T *_pL, U *_pR)
1323 {
1324     int iDims = _pR->getDims();
1325     int* piDims = _pR->getDimsArray();
1326     O* pOut = (O*)_pR->clone();
1327     double* pdblOut = pOut->get();
1328     double* pdblRight = _pR->get();
1329     double dblLeft = _pL->get(0);
1330     int iLeadDims = piDims[0];
1331     int* piIndex = new int[iDims];
1332     piIndex[0] = 0;
1333
1334     //find smaller dims
1335     for (int i = 1 ; i < iDims ; ++i)
1336     {
1337         //init
1338         piIndex[i] = 0;
1339
1340         if (iLeadDims > piDims[i])
1341         {
1342             iLeadDims = piDims[i];
1343         }
1344     }
1345
1346     for (int i = 0 ; i < iLeadDims ; ++i)
1347     {
1348         for (int j = 0 ; j < iDims ; ++j)
1349         {
1350             piIndex[j] = i;
1351         }
1352
1353         int index = _pR->getIndex(piIndex);
1354         add(dblLeft, pdblRight[index], pdblOut + index);
1355     }
1356
1357     delete[] piIndex;
1358     return pOut;
1359 }
1360
1361 template<class T, class U, class O>
1362 InternalType* add_I_MC(T *_pL, U *_pR)
1363 {
1364     return add_I_M<T, U, O>(_pL, _pR);
1365 }
1366
1367 template<class T, class U, class O>
1368 InternalType* add_IC_M(T *_pL, U *_pR)
1369 {
1370     int iDims = _pR->getDims();
1371     int* piDims = _pR->getDimsArray();
1372     O* pOut = (O*)_pR->clone();
1373     pOut->setComplex(true);
1374     int iLeadDims = piDims[0];
1375     int* piIndex = new int[iDims];
1376     piIndex[0] = 0;
1377     //find smaller dims
1378     for (int i = 1 ; i < iDims ; ++i)
1379     {
1380         //init
1381         piIndex[i] = 0;
1382
1383         if (iLeadDims > piDims[i])
1384         {
1385             iLeadDims = piDims[i];
1386         }
1387     }
1388
1389     for (int i = 0 ; i < iLeadDims ; ++i)
1390     {
1391         for (int j = 0 ; j < iDims ; ++j)
1392         {
1393             piIndex[j] = i;
1394         }
1395
1396         int index = _pR->getIndex(piIndex);
1397         add(_pR->get() + index, 1, _pL->get(0), _pL->getImg(0), pOut->get() + index, pOut->getImg() + index);
1398     }
1399
1400     delete[] piIndex;
1401     return pOut;
1402 }
1403
1404 template<class T, class U, class O>
1405 InternalType* add_IC_MC(T *_pL, U *_pR)
1406 {
1407     int iDims = _pR->getDims();
1408     int* piDims = _pR->getDimsArray();
1409     O* pOut = (O*)_pR->clone();
1410     int iLeadDims = piDims[0];
1411     int* piIndex = new int[iDims];
1412     piIndex[0] = 0;
1413     //find smaller dims
1414     for (int i = 1 ; i < iDims ; ++i)
1415     {
1416         //init
1417         piIndex[i] = 0;
1418
1419         if (iLeadDims > piDims[i])
1420         {
1421             iLeadDims = piDims[i];
1422         }
1423     }
1424
1425     for (int i = 0 ; i < iLeadDims ; ++i)
1426     {
1427         for (int j = 0 ; j < iDims ; ++j)
1428         {
1429             piIndex[j] = i;
1430         }
1431
1432         int index = _pR->getIndex(piIndex);
1433
1434         add(_pL->get(0), _pL->getImg(0), _pR->get(index), _pR->getImg(index), pOut->get() + index, pOut->getImg() + index);
1435     }
1436
1437     delete[] piIndex;
1438     return pOut;
1439 }
1440
1441 template<class T, class U, class O>
1442 InternalType* add_I_S(T *_pL, U *_pR)
1443 {
1444     O* pOut = new O(0);
1445     add(_pL->get(0), _pR->get(0), pOut->get());
1446     return pOut;
1447 }
1448
1449 template<class T, class U, class O>
1450 InternalType* add_IC_S(T *_pL, U *_pR)
1451 {
1452     O* pOut = new O(0.0, 0.0);
1453     add( _pR->get(), 1, _pL->get(0), _pL->getImg(0), pOut->get(), pOut->getImg());
1454     return pOut;
1455 }
1456
1457 template<class T, class U, class O>
1458 InternalType* add_I_SC(T *_pL, U *_pR)
1459 {
1460     O* pOut = new O(0.0, 0.0);
1461     add(_pL->get(), 1, _pR->get(0), _pR->getImg(0), pOut->get(), pOut->getImg());
1462     return pOut;
1463 }
1464
1465 template<class T, class U, class O>
1466 InternalType* add_IC_SC(T *_pL, U *_pR)
1467 {
1468     O* pOut = new O(0.0, 0.0);
1469     add(_pL->get(), _pL->getImg(), 1, _pR->get(0), _pR->getImg(0), pOut->get(), pOut->getImg());
1470     return pOut;
1471 }
1472
1473 template<class T, class U, class O> InternalType* add_M_I(T *_pL, U *_pR)
1474 {
1475     return add_I_M<U, T, O>(_pR, _pL);
1476 }
1477
1478 template<class T, class U, class O> InternalType* add_MC_I(T *_pL, U *_pR)
1479 {
1480     return add_I_MC<U, T, O>(_pR, _pL);
1481 }
1482
1483 template<class T, class U, class O> InternalType* add_M_IC(T *_pL, U *_pR)
1484 {
1485     return add_IC_M<U, T, O>(_pR, _pL);
1486 }
1487
1488 template<class T, class U, class O> InternalType* add_MC_IC(T *_pL, U *_pR)
1489 {
1490     return add_IC_MC<U, T, O>(_pR, _pL);
1491 }
1492
1493 template<class T, class U, class O> InternalType* add_S_I(T *_pL, U *_pR)
1494 {
1495     return add_I_S<U, T, O>(_pR, _pL);
1496 }
1497
1498 template<class T, class U, class O> InternalType* add_SC_I(T *_pL, U *_pR)
1499 {
1500     return add_I_SC<U, T, O>(_pR, _pL);
1501 }
1502
1503 template<class T, class U, class O> InternalType* add_S_IC(T *_pL, U *_pR)
1504 {
1505     return add_IC_S<U, T, O>(_pR, _pL);
1506 }
1507
1508 template<class T, class U, class O> InternalType* add_SC_IC(T *_pL, U *_pR)
1509 {
1510     return add_IC_SC<U, T, O>(_pR, _pL);
1511 }
1512
1513 template<class T, class U, class O> InternalType* add_I_I(T *_pL, U *_pR)
1514 {
1515     O* pOut = (O*)_pL->clone();
1516     add(_pL->get(0), _pR->get(0), pOut->get());
1517     return pOut;
1518 }
1519
1520 template<class T, class U, class O> InternalType* add_I_IC(T *_pL, U *_pR)
1521 {
1522     O* pOut = (O*)_pR->clone();
1523     add(_pL->get(), 1, _pR->get(0), _pR->getImg(0), pOut->get(), pOut->getImg());
1524     return pOut;
1525 }
1526
1527 template<class T, class U, class O> InternalType* add_IC_I(T *_pL, U *_pR)
1528 {
1529     return add_I_IC<U, T, O>(_pR, _pL);
1530 }
1531
1532 template<class T, class U, class O> InternalType* add_IC_IC(T *_pL, U *_pR)
1533 {
1534     O* pOut = (O*)_pL->clone();
1535     add(_pL->get(0), _pL->getImg(0), _pR->get(0), _pR->getImg(0), pOut->get(), pOut->getImg());
1536     return pOut;
1537 }
1538
1539 template<class T, class U, class O> types::InternalType* add_I_E(T *_pL, U * /*_pR*/)
1540 {
1541     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1542     Double* pOut = Double::Empty();
1543     add();
1544     return pOut;
1545 }
1546
1547 template<class T, class U, class O> types::InternalType* add_IC_E(T *_pL, U * /*_pR*/)
1548 {
1549     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1550     Double* pOut = Double::Empty();
1551     add();
1552     return pOut;
1553 }
1554
1555 template<class T, class U, class O> types::InternalType* add_E_I(T * /*_pL*/, U *_pR)
1556 {
1557     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1558     Double* pOut = Double::Empty();
1559     add();
1560     return pOut;
1561 }
1562
1563 template<class T, class U, class O> types::InternalType* add_E_IC(T * /*_pL*/, U *_pR)
1564 {
1565     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1566     Double* pOut = Double::Empty();
1567     add();
1568     return pOut;
1569 }
1570
1571 //specifiaction for String Matrix + String Matrix
1572 template<>
1573 InternalType* add_M_M<String, String, String>(String* _pL, String* _pR)
1574 {
1575     int iDimsL = _pL->getDims();
1576     int iDimsR = _pR->getDims();
1577
1578     if (iDimsL != iDimsR)
1579     {
1580         return nullptr;
1581     }
1582
1583     int* piDimsL = _pL->getDimsArray();
1584     int* piDimsR = _pR->getDimsArray();
1585
1586     for (int i = 0 ; i < iDimsL ; ++i)
1587     {
1588         if (piDimsL[i] != piDimsR[i])
1589         {
1590             throw ast::InternalError(_W("Inconsistent row/column dimensions.\n"));
1591         }
1592     }
1593
1594     String* pOut = new String(iDimsL, piDimsL);
1595     int size = _pL->getSize();
1596     int* sizeOut = new int[size];
1597     for (int i = 0 ; i < size ; ++i)
1598     {
1599         wchar_t* pwstL = _pL->get(i);
1600         wchar_t* pwstR = _pR->get(i);
1601         int sizeL = (int)wcslen(pwstL);
1602         int sizeR = (int)wcslen(pwstR);
1603
1604         sizeOut[i] = sizeL + sizeR + 1;
1605         wchar_t* pwstOut = (wchar_t*) MALLOC(sizeOut[i] * sizeof(wchar_t));
1606         //assign ptr without strdup
1607         pOut->get()[i] = pwstOut;
1608     }
1609
1610     add(_pL->get(), size, _pR->get(), sizeOut, pOut->get());
1611     delete[] sizeOut;
1612     return pOut;
1613 }
1614
1615 //specifiaction for String Matrix + String Scalar
1616 template<>
1617 InternalType* add_S_M<String, String, String>(String* _pL, String* _pR)
1618 {
1619     String* pOut = new String(_pR->getDims(), _pR->getDimsArray());
1620     int size = _pR->getSize();
1621     int* sizeOut = new int[size];
1622     wchar_t* pwstL = _pL->get(0);
1623     int sizeL = (int)wcslen(pwstL);
1624
1625     for (int i = 0 ; i < size ; ++i)
1626     {
1627         wchar_t* pwstR = _pR->get(i);
1628         int sizeR = (int)wcslen(pwstR);
1629
1630         sizeOut[i] = sizeL + sizeR + 1;
1631         wchar_t* pwstOut = (wchar_t*) MALLOC(sizeOut[i] * sizeof(wchar_t));
1632         //assign ptr without strdup
1633         pOut->get()[i] = pwstOut;
1634     }
1635
1636     add(pwstL, size, _pR->get(), sizeOut, pOut->get());
1637     delete[] sizeOut;
1638     return pOut;
1639 }
1640
1641 //specifiaction for String Scalar + String MAtrix
1642 template<>
1643 InternalType* add_M_S<String, String, String>(String* _pL, String* _pR)
1644 {
1645     String* pOut = new String(_pL->getDims(), _pL->getDimsArray());
1646     int size = _pL->getSize();
1647     int* sizeOut = new int[size];
1648     wchar_t* pwstR = _pR->get(0);
1649     int sizeR = (int)wcslen(pwstR);
1650
1651     for (int i = 0 ; i < size ; ++i)
1652     {
1653         wchar_t* pwstL = _pL->get(i);
1654         int sizeL = (int)wcslen(pwstL);
1655
1656         sizeOut[i] = sizeL + sizeR + 1;
1657         wchar_t* pwstOut = (wchar_t*) MALLOC(sizeOut[i] * sizeof(wchar_t));
1658         //assign ptr without strdup
1659         pOut->get()[i] = pwstOut;
1660     }
1661
1662     add(_pL->get(), size, pwstR, sizeOut, pOut->get());
1663     delete[] sizeOut;
1664     return pOut;
1665 }
1666
1667 //specifiaction for String Scalar + String Scalar
1668 template<>
1669 InternalType* add_S_S<String, String, String>(String* _pL, String* _pR)
1670 {
1671     String* pOut = new String(1, 1);
1672     wchar_t* pwstL = _pL->get(0);
1673     wchar_t* pwstR = _pR->get(0);
1674     int sizeL = (int)wcslen(pwstL);
1675     int sizeR = (int)wcslen(pwstR);
1676
1677     int sizeOut = sizeL + sizeR + 1;
1678     wchar_t* pwstOut = (wchar_t*) MALLOC(sizeOut * sizeof(wchar_t));
1679     //assign ptr without strdup
1680     pOut->get()[0] = pwstOut;
1681     add(pwstL, pwstR, sizeOut, *pOut->get());
1682     return pOut;
1683 }
1684
1685 template<>
1686 InternalType* add_M_E<String, Double, String>(String* _pL, Double* /*_pR*/)
1687 {
1688     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1689     Double* pOut = Double::Empty();
1690     add();
1691     return pOut;
1692 }
1693
1694 template<>
1695 InternalType* add_S_E<String, Double, String>(String* _pL, Double* /*_pR*/)
1696 {
1697     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1698     Double* pOut = Double::Empty();
1699     add();
1700     return pOut;
1701 }
1702
1703 template<>
1704 InternalType* add_E_M<Double, String, String>(Double* /*_pL*/, String* _pR)
1705 {
1706     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1707     Double* pOut = Double::Empty();
1708     add();
1709     return pOut;
1710 }
1711
1712 template<>
1713 InternalType* add_E_S<Double, String, String>(Double* /*_pL*/, String* _pR)
1714 {
1715     Sciwarning(_("operation +: Warning adding a matrix with the empty matrix will give an empty matrix result.\n")); 
1716     Double* pOut = Double::Empty();
1717     add();
1718     return pOut;
1719 }
1720
1721 template<> InternalType* add_M_M<Polynom, Polynom, Polynom>(Polynom* _pL, Polynom* _pR)
1722 {
1723
1724     Polynom* pOut = NULL;
1725     if (_pL->getVariableName() != _pR->getVariableName())
1726     {
1727         std::wostringstream os;
1728         os << _W("variables don't have the same formal variable");
1729         //os << ((Location)e.right_get().getLocation()).getLocationString() << std::endl;
1730         throw ast::InternalError(os.str());
1731     }
1732     if (_pR->isIdentity())
1733     {
1734         SinglePoly *sp  = _pR->get(0);
1735
1736         int iDims = _pL->getDims();
1737         int* piDims = _pL->getDimsArray();
1738         int iLeadDims = piDims[0];
1739         int* piIndex = new int[iDims];
1740         piIndex[0] = 0;
1741         _pR->resize(piDims, iDims);
1742         //find smaller dims
1743         for (int i = 1 ; i < iDims ; ++i)
1744         {
1745             //init
1746             piIndex[i] = 0;
1747
1748             if (iLeadDims > piDims[i])
1749             {
1750                 iLeadDims = piDims[i];
1751             }
1752         }
1753         for (int i = 1 ; i < iLeadDims ; ++i)
1754         {
1755
1756             _pR->set(i, i, sp);
1757
1758         }
1759     };
1760     if (_pL->isIdentity())
1761     {
1762         SinglePoly *sp  = _pL->get(0);
1763
1764         int iDims = _pR->getDims();
1765         int* piDims = _pR->getDimsArray();
1766         int iLeadDims = piDims[0];
1767         int* piIndex = new int[iDims];
1768         piIndex[0] = 0;
1769         _pL->resize(piDims, iDims);
1770         //find smaller dims
1771         for (int i = 1 ; i < iDims ; ++i)
1772         {
1773             //init
1774             piIndex[i] = 0;
1775
1776             if (iLeadDims > piDims[i])
1777             {
1778                 iLeadDims = piDims[i];
1779             }
1780         }
1781
1782         for (int i = 1 ; i < iLeadDims ; ++i)
1783         {
1784             _pL->set(i, i, sp);
1785         }
1786     }
1787
1788
1789     if (_pL->isScalar())
1790     {
1791         int *pRank = new int[_pR->getSize()];
1792         int *pRank1 = new int[_pR->getSize()];
1793         int *pRank2 = new int[_pR->getSize()];
1794         bool bComplex1 = _pL->isComplex();
1795         bool bComplex2 = _pR->isComplex();
1796
1797         memset(pRank1, 0x00, _pR->getSize() * sizeof(int));
1798
1799         _pL->getRank(pRank1);
1800         _pR->getRank(pRank2);
1801         for (int i = 0 ; i < _pR->getSize() ; i++)
1802         {
1803             pRank[i] = std::max(pRank1[0], pRank2[i]);
1804         }
1805
1806         pOut = new Polynom(_pR->getVariableName(), _pR->getDims(), _pR->getDimsArray(), pRank);
1807         if (bComplex1 || bComplex2)
1808         {
1809             pOut->setComplex(true);
1810         }
1811
1812         //Result P1(0) + P2(i)
1813         SinglePoly *pCoef1 = _pL->get(0);
1814         double *p1R = pCoef1->get();
1815         double *p1I = pCoef1->getImg();
1816         for (int i = 0 ; i < _pR->getSize() ; i++)
1817         {
1818             SinglePoly *pCoef2 = _pR->get(i);
1819             double *p2R = pCoef2->get();
1820             double *p2I = pCoef2->getImg();
1821
1822             SinglePoly *pCoefR = pOut->get(i);
1823             double *pRR = pCoefR->get();
1824             double *pRI = pCoefR->getImg();
1825
1826             for (int j = 0 ; j < std::min(pRank1[0], pRank2[i]) + 1; j++)
1827             {
1828                 pRR[j] = p1R[j] + p2R[j];
1829             }
1830
1831             double *pTemp = (pRank1[0] > pRank2[i] ? p1R : p2R);
1832             for (int j = std::min(pRank1[0], pRank2[i]) + 1; j < std::max(pRank1[0], pRank2[i]) + 1; j++)
1833             {
1834                 pRR[j] = pTemp[j];
1835             }
1836
1837             if (pOut->isComplex())
1838             {
1839                 for (int j = 0 ; j < std::min(pRank1[0], pRank2[i]) + 1; j++)
1840                 {
1841                     pRI[j] = (p1I == NULL ? 0 : p1I[j]) + (p2I == NULL ? 0 : p2I[j]);
1842                 }
1843
1844                 double *pTemp = (pRank1[0] > pRank2[i] ? p1I : p2I);
1845                 for (int j = std::min(pRank1[0], pRank2[i]) + 1; j < std::max(pRank1[0], pRank2[i]) + 1; j++)
1846                 {
1847                     pRI[j] = pTemp == NULL ? 0 : pTemp[j];
1848                 }
1849             }
1850         }
1851
1852         delete[] pRank;
1853         delete[] pRank1;
1854         delete[] pRank2;
1855         return pOut;
1856     }
1857
1858     if (_pR->isScalar())
1859     {
1860         int *pRank = new int[_pL->getSize()];
1861         int *pRank1 = new int[_pL->getSize()];
1862         int *pRank2 = new int[_pL->getSize()];
1863         bool bComplex1 = _pL->isComplex();
1864         bool bComplex2 = _pR->isComplex();
1865
1866         memset(pRank2, 0x00, _pL->getSize() * sizeof(int));
1867
1868         _pL->getRank(pRank1);
1869         _pR->getRank(pRank2);
1870         for (int i = 0 ; i < _pL->getSize() ; i++)
1871         {
1872             pRank[i] = std::max(pRank1[i], pRank2[0]);
1873         }
1874
1875         pOut = new Polynom(_pL->getVariableName(), _pL->getDims(), _pL->getDimsArray(), pRank);
1876         if (bComplex1 || bComplex2)
1877         {
1878             pOut->setComplex(true);
1879         }
1880
1881         //Result P1(i) + P2(0)
1882         SinglePoly *pCoef2 = _pR->get(0);
1883         double *p2R = pCoef2->get();
1884         double *p2I = pCoef2->getImg();
1885
1886         for (int i = 0 ; i < _pL->getSize() ; i++)
1887         {
1888             SinglePoly *pCoef1 = _pL->get(i);
1889             double *p1R = pCoef1->get();
1890             double *p1I = pCoef1->getImg();
1891
1892             SinglePoly *pCoefR = pOut->get(i);
1893             double *pRR = pCoefR->get();
1894             double *pRI = pCoefR->getImg();
1895
1896             for (int j = 0 ; j < std::min(pRank1[i], pRank2[0]) + 1 ; j++)
1897             {
1898                 pRR[j] = p1R[j] + p2R[j];
1899             }
1900
1901             double *pTemp = (pRank1[i] > pRank2[0] ? p1R : p2R);
1902             for (int j = std::min(pRank1[i], pRank2[0]) + 1; j < std::max(pRank1[i], pRank2[0]) + 1; j++)
1903             {
1904                 pRR[j] = pTemp[j];
1905             }
1906
1907             if (pOut->isComplex())
1908             {
1909                 for (int j = 0 ; j < std::min(pRank1[i], pRank2[0]) + 1; j++)
1910                 {
1911                     pRI[j] = (p1I == NULL ? 0 : p1I[j]) + (p2I == NULL ? 0 : p2I[j]);
1912                 }
1913
1914                 double *pTemp = (pRank1[i] > pRank2[0] ? p1I : p2I);
1915                 for (int j = std::min(pRank1[i], pRank2[0]) + 1; j < std::max(pRank1[i], pRank2[0]) + 1; j++)
1916                 {
1917                     pRI[j] = pTemp == NULL ? 0 : pTemp[j];
1918                 }
1919             }
1920         }
1921
1922         delete[] pRank;
1923         delete[] pRank1;
1924         delete[] pRank2;
1925         return pOut;
1926     }
1927
1928     int iDims1 = _pL->getDims();
1929     int iDims2 = _pR->getDims();
1930
1931     if (iDims1 != iDims2)
1932     {
1933         return nullptr;
1934     }
1935
1936     int* piDims1 = _pL->getDimsArray();
1937     int* piDims2 = _pR->getDimsArray();
1938
1939     for (int i = 0 ; i < iDims1 ; i++)
1940     {
1941         if ((piDims1[i] != piDims2[i]))
1942         {
1943             wchar_t pMsg[bsiz];
1944             os_swprintf(pMsg, bsiz, _W("Error: operator %ls: Matrix dimensions must agree (op1 is %ls, op2 is %ls).\n").c_str(),  L"+", _pL->DimToString().c_str(), _pR->DimToString().c_str());
1945             throw ast::InternalError(pMsg);
1946         }
1947     }
1948
1949     int *pRank = new int[_pL->getSize()];
1950     int *pRank1 = new int[_pL->getSize()];
1951     int *pRank2 = new int[_pR->getSize()];
1952     bool bComplex1 = _pL->isComplex();
1953     bool bComplex2 = _pR->isComplex();
1954
1955     _pL->getRank(pRank1);
1956     _pR->getRank(pRank2);
1957     for (int i = 0 ; i < _pL->getSize() ; i++)
1958     {
1959         pRank[i] = std::max(pRank1[i], pRank2[i]);
1960     }
1961
1962     pOut = new Polynom(_pR->getVariableName(), _pL->getDims(), _pL->getDimsArray(), pRank);
1963     if (_pL->isComplex() || _pR->isComplex())
1964     {
1965         pOut->setComplex(true);
1966     }
1967
1968     if (bComplex1 == false && bComplex2 == false)
1969     {
1970         for (int i = 0 ; i < _pL->getSize() ; i++)
1971         {
1972             iAddScilabPolynomToScilabPolynom(
1973                 _pL->get(i)->get(), pRank1[i] + 1,
1974                 _pR->get(i)->get(), pRank2[i] + 1,
1975                 pOut->get(i)->get(), pRank[i] + 1);
1976         }
1977     }
1978     else if (bComplex1 == false && bComplex2 == true)
1979     {
1980         for (int i = 0 ; i < _pL->getSize() ; i++)
1981         {
1982             iAddScilabPolynomToComplexPoly(
1983                 _pL->get(i)->get(), pRank1[i] + 1,
1984                 _pR->get(i)->get(), _pR->get(i)->getImg(), pRank2[i] + 1,
1985                 pOut->get(i)->get(), pOut->get(i)->getImg(), pRank[i] + 1);
1986         }
1987     }
1988     else if (bComplex1 == true && bComplex2 == false)
1989     {
1990         for (int i = 0 ; i < _pL->getSize() ; i++)
1991         {
1992             iAddScilabPolynomToComplexPoly(
1993                 _pR->get(i)->get(), pRank2[i] + 1,
1994                 _pL->get(i)->get(), _pL->get(i)->getImg(), pRank1[i] + 1,
1995                 pOut->get(i)->get(), pOut->get(i)->getImg(), pRank[i] + 1);
1996         }
1997     }
1998     else if (bComplex1 == true && bComplex2 == true)
1999     {
2000         for (int i = 0 ; i < _pL->getSize() ; i++)
2001         {
2002             iAddComplexPolyToComplexPoly(
2003                 _pL->get(i)->get(), _pL->get(i)->getImg(), pRank1[i] + 1,
2004                 _pR->get(i)->get(), _pR->get(i)->getImg(), pRank2[i] + 1,
2005                 pOut->get(i)->get(), pOut->get(i)->getImg(), pRank[i] + 1);
2006         }
2007     }
2008
2009     delete[] pRank;
2010     delete[] pRank1;
2011     delete[] pRank2;
2012
2013     if (pOut != NULL)
2014     {
2015         pOut->updateRank();
2016     }
2017
2018     return pOut;
2019 }
2020
2021 template<> InternalType* add_M_M<Polynom, Double, Polynom>(Polynom* _pL, Double* _pR)
2022 {
2023     return add_M_M<Double, Polynom, Polynom>(_pR, _pL);
2024 }
2025
2026 template<> InternalType* add_M_M<Double, Polynom, Polynom>(Double* _pL, Polynom* _pR)
2027 {
2028     Polynom* pOut = NULL;
2029     bool bComplex1 = _pR->isComplex();
2030     bool bComplex2 = _pL->isComplex();
2031
2032     double *pInDblR = _pL->getReal();
2033     double *pInDblI = _pL->getImg();
2034
2035     if (_pL->isEmpty())
2036     {
2037         return _pR;
2038     }
2039
2040     if (_pR->isScalar())
2041     {
2042         int *piRank = new int[_pL->getSize()];
2043         for (int i = 0 ; i < _pL->getSize() ; i++)
2044         {
2045             piRank[i] = _pR->get(0)->getRank();
2046         }
2047
2048         pOut = new Polynom(_pR->getVariableName(), _pL->getDims(), _pL->getDimsArray(), piRank);
2049         delete[] piRank;
2050         if (bComplex1 || bComplex2)
2051         {
2052             pOut->setComplex(true);
2053         }
2054
2055         for (int i = 0 ; i < pOut->getSize() ; i++)
2056         {
2057             SinglePoly *pInPoly  = _pR->get(0);
2058             SinglePoly *pOutPoly = pOut->get(i);
2059             double *pInPolyR     = pInPoly->get();
2060             double *pOutPolyR    = pOutPoly->get();
2061
2062             pOutPolyR[0] = pInDblR[i] + pInPolyR[0];
2063
2064             for (int j = 1 ; j < pInPoly->getSize() ; j++)
2065             {
2066                 pOutPolyR[j] = pInPolyR[j];
2067             }
2068         }
2069
2070         if (pOut->isComplex())
2071         {
2072             for (int i = 0 ; i < pOut->getSize() ; i++)
2073             {
2074                 SinglePoly *pInPoly  = _pR->get(0);
2075                 SinglePoly *pOutPoly = pOut->get(i);
2076                 double *pInPolyI     = pInPoly->getImg();
2077                 double *pOutPolyI    = pOutPoly->getImg();
2078
2079                 pOutPolyI[0] = (pInDblI != NULL ? pInDblI[i] : 0) + (pInPolyI != NULL ? pInPolyI[0] : 0);
2080
2081                 for (int j = 1 ; j < pInPoly->getSize() ; j++)
2082                 {
2083                     pOutPolyI[j] = (pInPolyI != NULL ? pInPolyI[j] : 0);
2084                 }
2085             }
2086         }
2087
2088         return pOut;
2089     }
2090
2091     if (_pL->isScalar())
2092     {
2093         pOut = (Polynom*)_pR->clone();
2094
2095         if (bComplex1 && bComplex2)
2096         {
2097             for (int i = 0 ; i < pOut->getSize() ; i++)
2098             {
2099                 SinglePoly *pSPOut   = pOut->get(i);
2100                 double *pOutPolyR    = pSPOut->get();
2101                 double *pOutPolyI    = pSPOut->getImg();
2102
2103                 pOutPolyR[0] += pInDblR[0];
2104                 pOutPolyI[0] += pInDblI[0];
2105             }
2106         }
2107         else if (bComplex2)
2108         {
2109             pOut->setComplex(true);
2110             for (int i = 0 ; i < pOut->getSize() ; i++)
2111             {
2112                 SinglePoly *pSPOut   = pOut->get(i);
2113                 double *pOutPolyR    = pSPOut->get();
2114                 double *pOutPolyI    = pSPOut->getImg();
2115
2116                 pOutPolyR[0] += pInDblR[0];
2117                 pOutPolyI[0] = pInDblI[0];
2118             }
2119         }
2120         else
2121         {
2122             for (int i = 0 ; i < pOut->getSize() ; i++)
2123             {
2124                 SinglePoly *pSPOut = pOut->get(i);
2125                 double *pOutPolyR  = pSPOut->get();
2126
2127                 pOutPolyR[0] += pInDblR[0];
2128             }
2129         }
2130
2131         return pOut;
2132     }
2133
2134     int iDims1 = _pR->getDims();
2135     int iDims2 = _pL->getDims();
2136
2137     if (iDims1 != iDims2)
2138     {
2139         return nullptr;
2140     }
2141
2142     int* piDims1 = _pR->getDimsArray();
2143     int* piDims2 = _pL->getDimsArray();
2144
2145     for (int i = 0 ; i < iDims1 ; i++)
2146     {
2147         if (piDims1[i] != piDims2[i])
2148         {
2149             wchar_t pMsg[bsiz];
2150             os_swprintf(pMsg, bsiz, _W("Error: operator %ls: Matrix dimensions must agree (op1 is %ls, op2 is %ls).\n").c_str(),  L"+", _pL->DimToString().c_str(), _pR->DimToString().c_str());
2151             throw ast::InternalError(pMsg);
2152         }
2153     }
2154
2155     pOut = (Polynom*)_pR->clone();
2156     if (bComplex1 && bComplex2)
2157     {
2158         for (int i = 0 ; i < pOut->getSize() ; i++)
2159         {
2160             SinglePoly *pSPOut   = pOut->get(i);
2161             double *pOutPolyR    = pSPOut->get();
2162             double *pOutPolyI    = pSPOut->getImg();
2163
2164             pOutPolyR[0] += pInDblR[i];
2165             pOutPolyI[0] += pInDblI[i];
2166         }
2167     }
2168     else if (bComplex2)
2169     {
2170         pOut->setComplex(true);
2171         for (int i = 0 ; i < pOut->getSize() ; i++)
2172         {
2173             SinglePoly *pSPOut   = pOut->get(i);
2174             double *pOutPolyR    = pSPOut->get();
2175             double *pOutPolyI    = pSPOut->getImg();
2176
2177             pOutPolyR[0] += pInDblR[i];
2178             pOutPolyI[0] = pInDblI[i];
2179         }
2180     }
2181     else
2182     {
2183         for (int i = 0 ; i < pOut->getSize() ; i++)
2184         {
2185             SinglePoly *pSPOut = pOut->get(i);
2186             double *pOutPolyR  = pSPOut->get();
2187
2188             pOutPolyR[0] += pInDblR[i];
2189         }
2190     }
2191
2192     return pOut;
2193 }
2194
2195 //poly + eye
2196 template<> InternalType* add_M_I<Polynom, Double, Polynom>(Polynom* _pL, Double* _pR)
2197 {
2198     Polynom* pOut = (Polynom*)_pL->clone();
2199     bool isComplex = _pL->isComplex() || _pR->isComplex();
2200     pOut->setComplex(isComplex);
2201
2202     int iDims = _pL->getDims();
2203     int* piDims = _pL->getDimsArray();
2204     int iLeadDims = piDims[0];
2205     int* piIndex = new int[iDims];
2206     piIndex[0] = 0;
2207     //find smaller dims
2208     for (int i = 1 ; i < iDims ; ++i)
2209     {
2210         //init
2211         piIndex[i] = 0;
2212
2213         if (iLeadDims > piDims[i])
2214         {
2215             iLeadDims = piDims[i];
2216         }
2217     }
2218
2219     double dblR = _pR->get(0);
2220
2221     if (isComplex)
2222     {
2223         SinglePoly** pSP = pOut->get();
2224
2225         double dblI = 0;
2226         if (_pR->isComplex())
2227         {
2228             dblI = _pR->getImg(0);
2229         }
2230
2231         for (int i = 0 ; i < iLeadDims ; ++i)
2232         {
2233             for (int j = 0 ; j < iDims ; ++j)
2234             {
2235                 piIndex[j] = i;
2236             }
2237
2238             int index = _pL->getIndex(piIndex);
2239             add(dblR, dblI, pSP[index]->get(0), pSP[index]->getImg(0), pSP[index]->get(), pSP[index]->getImg());
2240         }
2241     }
2242     else
2243     {
2244         SinglePoly** pSP = pOut->get();
2245         for (int i = 0 ; i < iLeadDims ; ++i)
2246         {
2247             for (int j = 0 ; j < iDims ; ++j)
2248             {
2249                 piIndex[j] = i;
2250             }
2251
2252             int index = _pL->getIndex(piIndex);
2253             add(dblR, pSP[index]->get(0), pSP[index]->get());
2254         }
2255     }
2256
2257     delete[] piIndex;
2258     return pOut;
2259 }
2260
2261 template<> InternalType* add_I_M<Double, Polynom, Polynom>(Double* _pL, Polynom* _pR)
2262 {
2263     return add_M_I<Polynom, Double, Polynom>(_pR, _pL);
2264 }
2265
2266 //sp + sp
2267 template<> InternalType* add_M_M<Sparse, Sparse, Sparse>(Sparse* _pL, Sparse* _pR)
2268 {
2269     Sparse* pOut = NULL;
2270
2271     //check scalar hidden in a sparse ;)
2272     /* if (_pL->getRows() == 1 && _pL->getCols() == 1)
2273      {
2274          //do scalar + sp
2275          Double* pDbl = NULL;
2276          if (_pL->isComplex())
2277          {
2278              std::complex<double> dbl = _pL->getImg(0, 0);
2279              pDbl = new Double(dbl.real(), dbl.imag());
2280          }
2281          else
2282          {
2283              pDbl = new Double(_pL->get(0, 0));
2284          }
2285
2286          AddSparseToDouble(_pR, pDbl, (GenericType**)pOut);
2287          delete pDbl;
2288          return pOut;
2289      }
2290
2291      if (_pR->getRows() == 1 && _pR->getCols() == 1)
2292      {
2293          //do sp + scalar
2294          Double* pDbl = NULL;
2295          if (_pR->isComplex())
2296          {
2297              std::complex<double> dbl = _pR->getImg(0, 0);
2298              pDbl = new Double(dbl.real(), dbl.imag());
2299          }
2300          else
2301          {
2302              pDbl = new Double(_pR->get(0, 0));
2303          }
2304
2305          AddSparseToDouble(_pL, pDbl, (GenericType**)pOut);
2306          delete pDbl;
2307          return 0;
2308      }
2309
2310      if (_pL->getRows() != _pR->getRows() || _pL->getCols() != _pR->getCols())
2311      {
2312          //dimensions not match
2313          throw ast::InternalError(_W("Inconsistent row/column dimensions.\n"));
2314      }
2315
2316      if (_pL->nonZeros() == 0)
2317      {
2318          //sp([]) + sp
2319          return _pR;
2320      }
2321
2322      if (_pR->nonZeros() == 0)
2323      {
2324          //sp + sp([])
2325          return _pL;
2326      }*/
2327
2328     return _pL->add(*_pR);
2329 }
2330
2331 //d + sp
2332 template<> InternalType* add_M_M<Double, Sparse, Double>(Double* _pL, Sparse* _pR)
2333 {
2334     return add_M_M<Sparse, Double, Double>(_pR, _pL);
2335 }
2336
2337 //sp + d
2338 template<> InternalType* add_M_M<Sparse, Double, Double>(Sparse* _pL, Double* _pR)
2339 {
2340     Double* pOut = NULL;
2341     int iOne = 1; //fortran
2342     bool bComplex1 = _pL->isComplex();
2343     bool bComplex2 = _pR->isComplex();
2344
2345     if (_pL->isScalar() && _pR->isScalar())
2346     {
2347         //sp + d
2348         pOut = (Double*)_pR->clone();
2349         pOut->setComplex(bComplex1 | bComplex2);
2350         if (bComplex1)
2351         {
2352             std::complex<double> dbl = _pL->getImg(0, 0);
2353             pOut->set(0, pOut->get(0) + dbl.real());
2354             pOut->setImg(0, pOut->getImg(0) + dbl.imag());
2355         }
2356         else
2357         {
2358             pOut->set(0, pOut->get(0) + _pL->get(0, 0));
2359         }
2360
2361         return pOut;
2362     }
2363
2364     if (_pR->isScalar())
2365     {
2366         //SP + d
2367         pOut = new Double(_pL->getRows(), _pL->getCols(), bComplex1 | bComplex2);
2368         int iSize = _pL->getSize();
2369         double dblVal = _pR->get(0);
2370         C2F(dset)(&iSize, &dblVal, pOut->get(), &iOne);
2371         if (bComplex2)
2372         {
2373             double dblValI = _pR->getImg(0);
2374             C2F(dset)(&iSize, &dblValI, pOut->getImg(), &iOne);
2375         }
2376         else if (bComplex1)
2377         {
2378             //initialize imag part at 0
2379             double dblValI = 0;
2380             C2F(dset)(&iSize, &dblValI, pOut->getImg(), &iOne);
2381         }
2382
2383         int nonZeros = static_cast<int>(_pL->nonZeros());
2384         int* pRows = new int[nonZeros * 2];
2385         _pL->outputRowCol(pRows);
2386         int* pCols = pRows + nonZeros;
2387
2388         if (bComplex1)
2389         {
2390             for (int i = 0 ; i < nonZeros ; i++)
2391             {
2392                 int iRow = static_cast<int>(pRows[i]) - 1;
2393                 int iCol = static_cast<int>(pCols[i]) - 1;
2394                 std::complex<double> dbl = _pL->getImg(iRow, iCol);
2395                 pOut->set(iRow, iCol, pOut->get(iRow, iCol) + dbl.real());
2396                 pOut->setImg(iRow, iCol, pOut->getImg(iRow, iCol) + dbl.imag());
2397             }
2398         }
2399         else
2400         {
2401             for (int i = 0 ; i < nonZeros ; i++)
2402             {
2403                 int iRow = static_cast<int>(pRows[i]) - 1;
2404                 int iCol = static_cast<int>(pCols[i]) - 1;
2405                 pOut->set(iRow, iCol, pOut->get(iRow, iCol) + _pL->get(iRow, iCol));
2406             }
2407         }
2408
2409         //clear
2410         delete[] pRows;
2411
2412         return pOut;
2413     }
2414
2415     if (_pL->isScalar())
2416     {
2417         //sp + D
2418         pOut = (Double*)_pR->clone();
2419         pOut->setComplex(bComplex1 | bComplex2);
2420
2421         if (bComplex1)
2422         {
2423             double* pReal = pOut->get();
2424             double* pImg = pOut->getImg();
2425             int size = pOut->getSize();
2426             for (int i = 0 ; i < size ; i++)
2427             {
2428                 std::complex<double> dbl = _pL->getImg(0, 0);
2429                 pReal[i] += dbl.real();
2430                 pImg[i] += dbl.imag();
2431             }
2432         }
2433         else
2434         {
2435             double* pReal = pOut->get();
2436             int size = pOut->getSize();
2437             for (int i = 0 ; i < size ; i++)
2438             {
2439                 pReal[i] += _pL->get(0, 0);
2440             }
2441         }
2442
2443         return pOut;
2444     }
2445
2446
2447     if (_pR->getDims() == 2 && _pL->getRows() == _pR->getRows() && _pL->getCols() == _pR->getCols())
2448     {
2449         //SP + D
2450         pOut = (Double*)_pR->clone();
2451         pOut->setComplex(bComplex1 | bComplex2);
2452
2453         int nonZeros = static_cast<int>(_pL->nonZeros());
2454         int* pRows = new int[nonZeros * 2];
2455         _pL->outputRowCol(pRows);
2456         int* pCols = pRows + nonZeros;
2457
2458         if (bComplex1)
2459         {
2460             for (int i = 0 ; i < nonZeros ; i++)
2461             {
2462                 int iRow = static_cast<int>(pRows[i]) - 1;
2463                 int iCol = static_cast<int>(pCols[i]) - 1;
2464                 std::complex<double> dbl = _pL->getImg(iRow, iCol);
2465                 pOut->set(iRow, iCol, pOut->get(iRow, iCol) + dbl.real());
2466                 pOut->setImg(iRow, iCol, pOut->getImg(iRow, iCol) + dbl.imag());
2467             }
2468         }
2469         else
2470         {
2471             for (int i = 0 ; i < nonZeros ; i++)
2472             {
2473                 int iRow = static_cast<int>(pRows[i]) - 1;
2474                 int iCol = static_cast<int>(pCols[i]) - 1;
2475                 pOut->set(iRow, iCol, pOut->get(iRow, iCol) + _pL->get(iRow, iCol));
2476             }
2477         }
2478
2479         //clear
2480         delete[] pRows;
2481         return pOut;
2482     }
2483     else
2484     {
2485         return nullptr;
2486     }
2487 }
2488
2489 //[] + sp
2490 template<> InternalType* add_M_M<Double, Sparse, Sparse>(Double* _pL, Sparse* _pR)
2491 {
2492     return add_M_M<Sparse, Double, Sparse>(_pR, _pL);
2493 }
2494
2495 //sp + []
2496 template<> InternalType* add_M_M<Sparse, Double, Sparse>(Sparse* _pL, Double* _pR)
2497 {
2498     Sparse* pOut = NULL;
2499     if (_pR->isIdentity())
2500     {
2501         //convert to _pL
2502         pOut  = _pL->clone()->getAs<Sparse>();
2503         bool isComplex = _pL->isComplex() || _pR->isComplex();
2504         if (isComplex)
2505         {
2506             pOut->toComplex();
2507         }
2508
2509         int size = std::min(_pL->getRows(), _pL->getCols());
2510         double dblR = _pR->get(0);
2511
2512         if (isComplex)
2513         {
2514             std::complex<double> cplx_add(dblR, 0);
2515             if (_pR->isComplex())
2516             {
2517                 cplx_add.imag(_pR->getImg(0));
2518             }
2519
2520             for (int i = 0 ; i < size ; i++)
2521             {
2522                 pOut->set(i, i, pOut->getImg(i, i) + cplx_add, false);
2523             }
2524         }
2525         else
2526         {
2527             for (int i = 0 ; i < size ; i++)
2528             {
2529                 pOut->set(i, i, _pL->get(i, i) + dblR, false);
2530             }
2531         }
2532
2533         pOut->finalize();
2534         return pOut;
2535     }
2536     else
2537     {
2538         //is []
2539         return _pL;
2540     }
2541 }