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