743632ea94597e74ea5ca33f4fe2258450fcf373
[scilab.git] / scilab / modules / signal_processing / sci_gateway / c / sci_conv2.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - INRIA - Serge STEER
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12 /*--------------------------------------------------------------------------*/
13 #include "core_math.h"
14 #include "stack-c.h"
15 #include "gw_signal.h"
16 #include "MALLOC.h"
17 #include "api_scilab.h"
18 #include "localization.h"
19 #include "Scierror.h"
20 #include "conv2.h"
21 /*--------------------------------------------------------------------------*/
22 int sci_conv2(char *fname,unsigned long fname_len)
23 {
24     SciErr sciErr;
25     int *piAddr = NULL;
26     char *option = NULL;
27     int iopt = 1;
28     double *Outr = NULL,*Outi = NULL;
29     int mOut = 0, nOut = 0;
30     int iType = 0;
31     int edgM = 0, edgN = 0;
32     int rhs = Rhs;
33
34     /* Check if last argument is one of the string "full", "same","valid" */
35     sciErr = getVarAddressFromPosition(pvApiCtx, Rhs, &piAddr);
36     if(sciErr.iErr)
37     {
38         printError(&sciErr, 0);
39         return 0;
40     }
41
42     if (isStringType(pvApiCtx, piAddr)) 
43     {
44         CheckRhs(3,4);
45         if(isScalar(pvApiCtx, piAddr)) 
46         {
47             if (getAllocatedSingleString(pvApiCtx, piAddr, &option)==0) 
48             {
49                 if (strcmp("full", option) == 0) 
50                 {
51                     iopt=1;
52                 }
53                 else if (strcmp("same", option) == 0) 
54                 {
55                     iopt=2;
56                 }
57                 else if (strcmp("valid", option) == 0) 
58                 {
59                     iopt=3;
60                 }
61                 else 
62                 {
63                     Scierror(999,_("%s: Wrong value for input argument #%d: '%s' or '%s' expected.\n"), 
64                         fname, Rhs, "\"full\", \"same\"","\"valid\"");
65                     freeAllocatedSingleString(option);
66                     option = NULL;
67                     return 0;
68                 }
69                 freeAllocatedSingleString(option);
70                 option = NULL;
71                 rhs=Rhs-1;
72             }
73             else 
74             {
75                 Scierror(999,_("%s: Wrong value for input argument #%d: '%s' or '%s' expected.\n"), 
76                     fname, Rhs, "\"full\", \"same\"","\"valid\"");
77                 return 0;
78             }
79         }
80     }
81     else 
82     {
83         CheckRhs(2,3); 
84     }
85
86     if (rhs==3) 
87     { 
88         /*separable conv2(C,R,A)*/
89         double *Cr = NULL,*Ci = NULL;
90         double *Rr = NULL,*Ri = NULL;
91         double *Ar = NULL,*Ai = NULL;
92         int mC = 0, nC = 0, mR = 0, nR = 0, mA = 0, nA = 0;
93
94         /* get and check C */
95         sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
96         if(sciErr.iErr)
97         {
98             printError(&sciErr, 0);
99             return 0;
100         }
101
102         //check type
103         sciErr = getVarType(pvApiCtx, piAddr, &iType);
104         if(sciErr.iErr)
105         {
106             printError(&sciErr, 0);
107             return 0;
108         }
109
110         if(iType != sci_matrix)
111         {
112             Scierror(999,_("%s: Wrong type for argument %d: Real vector expected.\n"), 
113                 fname, 1);
114             return 0;
115         }
116
117         //get complexity
118         if (isVarComplex(pvApiCtx, piAddr)) 
119         {
120             sciErr = getComplexMatrixOfDouble(pvApiCtx, piAddr, &mC, &nC, &Cr, &Ci);
121             if(sciErr.iErr)
122             {
123                 printError(&sciErr, 0);
124                 return 0;
125             }
126
127         }
128         else 
129         {
130             sciErr = getMatrixOfDouble(pvApiCtx, piAddr, &mC, &nC, &Cr);
131             if(sciErr.iErr)
132             {
133                 printError(&sciErr, 0);
134                 return 0;
135             }
136
137         }
138         if (mC>1 && nC>1) 
139         { 
140             /*check if vector*/
141             Scierror(999,_("%s: Wrong type for argument %d: Real or complex vector expected.\n"), 
142                 fname, 1);
143             return 0;
144         }
145         mC = mC*nC;
146
147         /* get and check R */
148         sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddr);
149         if(sciErr.iErr)
150         {
151             printError(&sciErr, 0);
152             return 0;
153         }
154
155         //check type
156         sciErr = getVarType(pvApiCtx, piAddr, &iType);
157         if(sciErr.iErr)
158         {
159             printError(&sciErr, 0);
160             return 0;
161         }
162
163         if(iType != sci_matrix)
164         {
165             Scierror(999,_("%s: Wrong type for argument %d: Real or complex vector expected.\n"), 
166                 fname, 2);
167             return 0;
168         }
169
170         //get complexity
171         if (isVarComplex(pvApiCtx, piAddr)) 
172         {
173             sciErr = getComplexMatrixOfDouble(pvApiCtx, piAddr, &mR, &nR, &Rr, &Ri);
174             if(sciErr.iErr)
175             {
176                 printError(&sciErr, 0);
177                 return 0;
178             }
179
180         }
181         else 
182         {
183             sciErr = getMatrixOfDouble(pvApiCtx, piAddr, &mR, &nR, &Rr);
184             if(sciErr.iErr)
185             {
186                 printError(&sciErr, 0);
187                 return 0;
188             }
189
190         }
191
192         if (mR>1 && nR>1) 
193         { 
194             /*check if vector*/
195             Scierror(999,_("%s: Wrong type for argument %d: Real vector expected.\n"), 
196                 fname, 2);
197             return 0;
198         }
199
200         nR = nR*mR;
201         /* get and check A */
202         sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddr);
203         if(sciErr.iErr)
204         {
205             printError(&sciErr, 0);
206             return 0;
207         }
208
209         //check type
210         sciErr = getVarType(pvApiCtx, piAddr, &iType);
211         if(sciErr.iErr)
212         {
213             printError(&sciErr, 0);
214             return 0;
215         }
216
217         if(iType != sci_matrix)
218         {
219             Scierror(999,_("%s: Wrong type for argument %d: Real or complex matrix expected.\n"), 
220                 fname, 3);
221             return 0;
222         }
223
224         //get complexity
225         if (isVarComplex(pvApiCtx, piAddr)) 
226         {
227             sciErr = getComplexMatrixOfDouble(pvApiCtx, piAddr, &mA, &nA, &Ar, &Ai);
228             if(sciErr.iErr)
229             {
230                 printError(&sciErr, 0);
231                 return 0;
232             }
233
234         }
235         else 
236         {
237             sciErr = getMatrixOfDouble(pvApiCtx, piAddr, &mA, &nA, &Ar);
238             if(sciErr.iErr)
239             {
240                 printError(&sciErr, 0);
241                 return 0;
242             }
243
244         }
245
246         //Compute result sizes
247         if (iopt == 1 ) 
248         {
249             if (mC==0||nR==0) 
250             {
251                 mOut= mA;
252                 nOut= nA;
253             }
254             else 
255             {
256                 mOut= mA + mC - 1;
257                 nOut= nA + nR - 1;
258             }
259             edgM= mC - 1;
260             edgN= nR - 1;
261         } 
262         else if ( iopt == 2 ) 
263         {
264             mOut= mA;
265             nOut= nA;
266             edgM= ( mC - 1) /2;
267             edgN= ( nR - 1) /2;
268         }
269         else if (iopt==3) 
270         {
271             if (mC==0||nR==0) 
272             {
273                 mOut= mA;
274                 nOut= nA;
275             }
276             else 
277             {
278                 mOut= Max(0,mA - mC + 1);
279                 nOut= Max(0,nA - nR + 1);
280             }
281             edgM = edgN= 0;
282         }
283
284         if (Ri==NULL&&Ci==NULL&&Ai==NULL)
285         { 
286             //real case
287             double *Tr = NULL;
288             //Allocate result
289             sciErr = allocMatrixOfDouble(pvApiCtx,Rhs+1,mOut,nOut,&Outr);
290             if(sciErr.iErr)
291             {
292                 printError(&sciErr, 0);
293                 return 0;
294             }
295
296             sciErr = allocMatrixOfDouble(pvApiCtx,Rhs+2,1,nA,&Tr);
297             if(sciErr.iErr)
298             {
299                 printError(&sciErr, 0);
300                 return 0;
301             }
302
303             conv2_separable_R(Rr,nR,Cr,mC,Ar,mA,nA,Outr,mOut,nOut,edgM,edgN,Tr);
304         }
305         else 
306         {
307             double *Tr = NULL,*Ti = NULL;
308             //Allocate result
309             sciErr = allocComplexMatrixOfDouble(pvApiCtx,Rhs+1,mOut,nOut,&Outr,&Outi);
310             if(sciErr.iErr)
311             {
312                 printError(&sciErr, 0);
313                 return 0;
314             }
315
316             sciErr = allocComplexMatrixOfDouble(pvApiCtx,Rhs+2,1,nA,&Tr,&Ti);
317             if(sciErr.iErr)
318             {
319                 printError(&sciErr, 0);
320                 return 0;
321             }
322
323             conv2_separable_C(Rr,Ri,nR,Cr,Ci,mC,Ar,Ai,mA,nA,Outr,Outi,mOut,nOut,edgM,edgN,Tr,Ti);
324         }
325     }
326     else 
327     {
328         /*conv2(A,B)*/
329         double *Ar = NULL,*Ai = NULL;
330         double *Br = NULL,*Bi = NULL;
331         int mA,nA,mB,nB;
332
333         /* get and check A */
334         sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
335         if(sciErr.iErr)
336         {
337             printError(&sciErr, 0);
338             return 0;
339         }
340
341         //check type
342         sciErr = getVarType(pvApiCtx, piAddr, &iType);
343         if(sciErr.iErr)
344         {
345             printError(&sciErr, 0);
346             return 0;
347         }
348
349         if(iType != sci_matrix)
350         {
351             Scierror(999,_("%s: Wrong type for argument %d: Real or complex matrix expected.\n"), 
352                 fname, 1);
353             return 0;
354         }
355
356         //get complexity
357         if (isVarComplex(pvApiCtx, piAddr)) 
358         {
359             sciErr = getComplexMatrixOfDouble(pvApiCtx, piAddr, &mA, &nA, &Ar, &Ai);
360             if(sciErr.iErr)
361             {
362                 printError(&sciErr, 0);
363                 return 0;
364             }
365
366         }
367         else 
368         {
369             sciErr = getMatrixOfDouble(pvApiCtx, piAddr, &mA, &nA, &Ar);
370             if(sciErr.iErr)
371             {
372                 printError(&sciErr, 0);
373                 return 0;
374             }
375
376         }
377
378         /* get and check B */
379         sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddr);
380         if(sciErr.iErr)
381         {
382             printError(&sciErr, 0);
383             return 0;
384         }
385
386         //check type
387         sciErr = getVarType(pvApiCtx, piAddr, &iType);
388         if(sciErr.iErr)
389         {
390             printError(&sciErr, 0);
391             return 0;
392         }
393
394         if(iType != sci_matrix)
395         {
396             Scierror(999,_("%s: Wrong type for argument %d: Real or complex matrix expected.\n"), 
397                 fname, 2);
398             return 0;
399         }
400
401         //get complexity
402         if (isVarComplex(pvApiCtx, piAddr)) 
403         {
404             sciErr = getComplexMatrixOfDouble(pvApiCtx, piAddr, &mB, &nB, &Br, &Bi);
405             if(sciErr.iErr)
406             {
407                 printError(&sciErr, 0);
408                 return 0;
409             }
410
411         }
412         else 
413         {
414             sciErr = getMatrixOfDouble(pvApiCtx, piAddr, &mB, &nB, &Br);
415             if(sciErr.iErr)
416             {
417                 printError(&sciErr, 0);
418                 return 0;
419             }
420
421         }
422
423         if (iopt==1) 
424         {
425             if (mA==0) 
426             {
427                 mOut= mB;
428                 nOut= nB;
429             }
430             else if (mB ==0) 
431             {
432                 mOut= mA;
433                 nOut= nA;
434             }
435             else  
436             { 
437                 mOut= mA + Max(0,mB - 1);
438                 nOut= nA +  Max(0,nB - 1);
439             }
440             edgM= mB - 1;
441             edgN= nB - 1;
442         } 
443         else if (iopt==2) 
444         {
445             mOut= mA;
446             nOut= nA;
447             edgM= ( mB - 1) /2;
448             edgN= ( nB - 1) /2;
449         } 
450         else if (iopt==3) 
451         {
452             if (mB ==0) 
453             {
454                 mOut=mA;
455                 nOut=nA;
456             }
457             else 
458             {
459                 mOut= Max(0,mA - mB + 1);
460                 nOut= Max(0,nA - nB + 1);
461             }
462             edgM= edgN= 0;
463         } 
464
465         if (Ai==NULL&&Bi==NULL)
466         { 
467             //real case
468             //Allocate result
469             sciErr = allocMatrixOfDouble(pvApiCtx, Rhs+1,mOut,nOut,&Outr);
470             if(sciErr.iErr)
471             {
472                 printError(&sciErr, 0);
473                 return 0;
474             }
475
476             conv2_R(Ar,mA,nA,Br,mB,nB,Outr,mOut,nOut,edgM,edgN);
477         }
478         else 
479         {
480             //Allocate result
481             sciErr = allocComplexMatrixOfDouble(pvApiCtx,Rhs+1,mOut,nOut,&Outr,&Outi);
482             if(sciErr.iErr)
483             {
484                 printError(&sciErr, 0);
485                 return 0;
486             }
487
488             conv2_C(Ar,Ai,mA,nA,Br,Bi,mB,nB,Outr,Outi,mOut,nOut,edgM,edgN);
489         }
490     }
491
492     LhsVar(1) = Rhs+1; 
493     PutLhsVar();
494     return 0;
495 }
496 /*--------------------------------------------------------------------------*/