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