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