Massive indent of all codes:
[scilab.git] / scilab / modules / signal_processing / sci_gateway / cpp / sci_corr.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - DIGITEO - Antoine ELIAS
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
14 #include "signal_gw.hxx"
15 #include "double.hxx"
16 #include "string.hxx"
17 #include "function.hxx"
18
19 extern "C"
20 {
21 #include "localization.h"
22 #include "Scierror.h"
23 #include "sciprint.h"
24
25     //fortran prototypes
26     extern void C2F(tscccf)(double *x, double *y, int *length, double *cxy, double *xymean, int *lag, int *error);
27
28 }
29
30 /*--------------------------------------------------------------------------*/
31 types::Function::ReturnValue sci_corr(types::typed_list &in, int _iRetCount, types::typed_list &out)
32 {
33     //check input parameters
34     if (in.size() < 2 || in.size() > 5)
35     {
36         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "corr", 2, 5);
37         return types::Function::Error;
38     }
39
40     //call format
41     if (in[0]->isString())
42     {
43         sciprint(_("%ls: Need to plug external call"), L"corr");
44         return types::Function::Error;
45
46         types::String* pS = in[0]->getAs<types::String>();
47         if (pS->getSize() == 1 && pS->get(0)[0] == L'f')
48         {
49             //[cov,mean]=corr('fft',xmacro,[ymacro],n,sect)
50             int iErr                    = 0;
51             int iSect                   = 0;
52             int iTotalSize              = 0;
53             int iSize                   = 0;
54             int iMode                   = 0;
55             types::Callable* pXFunction = NULL;
56             types::Callable* pYFunction = NULL;
57
58             //check input parameters
59             if (in.size() < 4 || in.size() > 5)
60             {
61                 Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "corr", 4, 5);
62                 return types::Function::Error;
63             }
64
65             //get parameter sect
66             int iPos = (int)(in.size() - 1);
67             if (in[iPos]->isDouble() == false || in[iPos]->getAs<types::Double>()->isScalar() == false)
68             {
69                 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "corr", iPos + 1);
70                 return types::Function::Error;
71             }
72
73             iSect = (int)in[iPos]->getAs<types::Double>()->get(0);
74
75             //get parameter n
76             iPos--;
77             if (in[iPos]->isDouble() == false || in[iPos]->getAs<types::Double>()->isScalar() == false)
78             {
79                 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "corr", iPos + 1);
80                 return types::Function::Error;
81             }
82
83             iTotalSize = (int)in[iPos]->getAs<types::Double>()->get(0);
84
85             //get xmacro
86             if (in[1]->isCallable() == false)
87             {
88                 Scierror(999, _("%s: Wrong type for input argument #%d: A function expected.\n"), "corr", 2);
89                 return types::Function::Error;
90             }
91
92             pXFunction = in[1]->getAs<types::Callable>();
93             iMode = 2;
94
95             if (in.size() == 5)
96             {
97                 //get ymacro
98                 if (in[2]->isCallable() == false)
99                 {
100                     Scierror(999, _("%s: Wrong type for input argument #%d: A function expected.\n"), "corr", 3);
101                     return types::Function::Error;
102                 }
103
104                 pYFunction = in[2]->getAs<types::Callable>();
105                 iMode = 3;
106             }
107
108         }
109         else if (pS->getSize() == 1 && pS->get(0)[0] == L'u')
110         {
111             //update
112         }
113         else
114         {
115             //error
116             Scierror(999, _("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"), "corr", 1, "'fft', 'update'");
117             return types::Function::Error;
118         }
119     }
120     else
121     {
122         //usual case [cov,mean]=corr(x,[y],nlags)
123         int iErr                        = 0;
124         int iCorrelation                = 0;
125         types::Double* pDblX            = NULL;
126         types::Double* pDblY            = NULL;
127         types::Double* pDblCorrelation  = NULL;
128         types::Double* pDblMean         = NULL;
129         int iSize                       = 0;
130         double pdblMean[2];
131
132
133         //check input parameters
134         if (in.size() < 2 || in.size() > 3)
135         {
136             Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "corr", 2, 3);
137             return types::Function::Error;
138         }
139
140         //get last parameter nlags
141         int iPos = (int)(in.size() - 1);
142         if (in[iPos]->isDouble() == false || in[iPos]->getAs<types::Double>()->isScalar() == false)
143         {
144             Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "corr", iPos + 1);
145             return types::Function::Error;
146         }
147
148         iCorrelation = (int)in[iPos]->getAs<types::Double>()->get(0);
149         pDblCorrelation = new types::Double(1, iCorrelation);
150
151         if (in.size() == 3)
152         {
153             if (in[1]->isDouble() == false)
154             {
155                 Scierror(999, _("%s: Wrong type for input argument #%d: Matrix expected.\n"), "corr" , 2);
156                 return types::Function::Error;
157             }
158
159             pDblY = in[1]->getAs<types::Double>();
160
161             if (in[0]->isDouble() == false)
162             {
163                 Scierror(999, _("%s: Wrong type for input argument #%d: Matrix expected.\n"), "corr" , 1);
164                 return types::Function::Error;
165             }
166
167             pDblX = in[0]->getAs<types::Double>();
168
169             if (pDblX->getSize() != pDblY->getSize())
170             {
171                 Scierror(60, _("%s: Wrong size for argument: Incompatible dimensions.\n"), "corr");
172                 return types::Function::Error;
173             }
174         }
175         else
176         {
177             if (in[0]->isDouble() == false)
178             {
179                 Scierror(999, _("%s: Wrong type for input argument #%d: Matrix expected.\n"), "corr" , 1);
180                 return types::Function::Error;
181             }
182
183             pDblX = in[0]->getAs<types::Double>();
184             pDblY = pDblX;
185         }
186
187         iSize = pDblX->getSize();
188
189         C2F(tscccf)(pDblX->get(), pDblY->get(), &iSize, pDblCorrelation->get(), pdblMean, &iCorrelation, &iErr);
190         if (iErr == -1)
191         {
192             Scierror(999, _("%s: Too many coefficients are required.\n"), "corr");
193             return types::Function::Error;
194         }
195
196         out.push_back(pDblCorrelation);
197
198         if (_iRetCount == 2)
199         {
200             if (in.size() == 3)
201             {
202                 pDblMean = new types::Double(1, 2);
203             }
204             else
205             {
206                 pDblMean = new types::Double(1, 1);
207             }
208
209             pDblMean->set(pdblMean);
210             out.push_back(pDblMean);
211         }
212     }
213     return types::Function::OK;
214 }