corr('fft', ...)
[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 * Copyright (C) 2014 - Scilab Enterprises - Anais AUBERT
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
15 #include "signal_gw.hxx"
16 #include "double.hxx"
17 #include "string.hxx"
18 #include "internal.hxx"
19 #include "function.hxx"
20 #include "signalprocessingfunctions.hxx"
21
22 extern "C"
23 {
24 #include "localization.h"
25 #include "Scierror.h"
26 #include "sciprint.h"
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         types::String* pS = in[0]->getAs<types::String>();
44         if (pS->getSize() == 1 && pS->get(0)[0] == L'f')
45         {
46             //[cov,mean]=corr('fft',xmacro,[ymacro],n,sect)
47             types::InternalType* pXFunction = NULL;
48             types::InternalType* pYFunction = NULL;
49
50             int iErr        = 0;
51             int iSect       = 0;
52             int iOutSize    = 0;
53             int iTotalSize  = 0;
54             int iSize       = 0;
55             int iMode       = 0;
56
57             double* xa = NULL;
58             double* xi = NULL;
59             double* xr = NULL;
60             double* zr = NULL;
61             double* zi = NULL;
62
63             char *dx = NULL;
64             char *dy = NULL;
65             bool bOK = false;
66
67             //check input parameters
68             if (in.size() < 4 || in.size() > 5)
69             {
70                 Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "corr", 4, 5);
71                 return types::Function::Error;
72             }
73
74             //get parameter sect
75             int iPos = (int)(in.size() - 1);
76             if (in[iPos]->isDouble() == false || in[iPos]->getAs<types::Double>()->isScalar() == false)
77             {
78                 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "corr", iPos + 1);
79                 return types::Function::Error;
80             }
81
82             iOutSize = (int)in[iPos]->getAs<types::Double>()->get(0);
83             iSect = iOutSize * 2;
84
85             //get parameter n
86             iPos--;
87             if (in[iPos]->isDouble() == false || in[iPos]->getAs<types::Double>()->isScalar() == false)
88             {
89                 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "corr", iPos + 1);
90                 return types::Function::Error;
91             }
92
93             iTotalSize = (int)in[iPos]->getAs<types::Double>()->get(0);
94
95             Signalprocessingfunctions* spFunctionsManager = new Signalprocessingfunctions(L"corr");
96             Signalprocessing::addSignalprocessingfunctions(spFunctionsManager);
97
98             //get xmacro
99             if (in[1]->isCallable())
100             {
101                 pXFunction = in[1]->getAs<types::Callable>();
102                 spFunctionsManager->setDgetx(in[1]->getAs<types::Callable>());
103             }
104             else if (in[1]->isString())
105             {
106                 pXFunction = in[1]->getAs<types::String>();
107                 spFunctionsManager->setDgetx(in[1]->getAs<types::String>());
108             }
109             else
110             {
111                 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "corr", iPos + 1);
112                 return types::Function::Error;
113             }
114
115             iMode = 2;
116
117             if (in.size() == 5)
118             {
119                 //get ymacro
120                 if (in[2]->isCallable())
121                 {
122                     pYFunction = in[2]->getAs<types::Callable>();
123                     spFunctionsManager->setDgety(in[2]->getAs<types::Callable>());
124                 }
125                 else if (in[2]->isString())
126                 {
127                     pYFunction = in[2]->getAs<types::String>();
128                     spFunctionsManager->setDgety(in[2]->getAs<types::String>());
129                 }
130                 else
131                 {
132                     Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "corr", iPos + 2);
133                     return types::Function::Error;
134                 }
135
136                 iMode = 3;
137             }
138
139             xa = new double[iSect];
140             xr = new double[iSect];
141             xi = new double[iSect];
142             zr = new double[iSect / 2 + 1];
143             zi = new double[iSect / 2 + 1];
144             C2F(cmpse2)(&iSect, &iTotalSize, &iMode, (void*) dgetx_f, (void*) dgety_f, xa, xr, xi, zr, zi, &iErr);
145
146             delete[] xi;
147             delete[] zr;
148             delete[] zi;
149
150             if (iErr > 0)
151             {
152                 delete[] xa;
153                 delete[] xr;
154                 Scierror(999, _("fft call : needs power of two!"));
155                 return types::Function::Error;
156             }
157
158             types::Double *pDblOut1 = new types::Double(1, iOutSize);
159             pDblOut1->set(xa);
160             delete[] xa;
161             out.push_back(pDblOut1);
162
163             types::Double *pDblOut2 = new types::Double(1, iMode - 1);
164             pDblOut2->set(xr);
165             delete[] xr;
166             out.push_back(pDblOut2);
167
168             return types::Function::OK;
169         }
170         else if (pS->getSize() == 1 && pS->get(0)[0] == L'u')
171         {
172             //update
173         }
174         else
175         {
176             //error
177             Scierror(999, _("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"), "corr", 1, "'fft', 'update'");
178             return types::Function::Error;
179         }
180     }
181     else
182     {
183         //usual case [cov,mean]=corr(x,[y],nlags)
184         int iErr                        = 0;
185         int iCorrelation                = 0;
186         types::Double* pDblX            = NULL;
187         types::Double* pDblY            = NULL;
188         types::Double* pDblCorrelation  = NULL;
189         types::Double* pDblMean         = NULL;
190         int iSize                       = 0;
191         double pdblMean[2];
192
193         //check input parameters
194         if (in.size() < 2 || in.size() > 3)
195         {
196             Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "corr", 2, 3);
197             return types::Function::Error;
198         }
199
200         //get last parameter nlags
201         int iPos = (int)(in.size() - 1);
202         if (in[iPos]->isDouble() == false || in[iPos]->getAs<types::Double>()->isScalar() == false)
203         {
204             Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "corr", iPos + 1);
205             return types::Function::Error;
206         }
207
208         iCorrelation = (int)in[iPos]->getAs<types::Double>()->get(0);
209
210         if (in.size() == 3)
211         {
212             if (in[1]->isDouble() == false)
213             {
214                 Scierror(999, _("%s: Wrong type for input argument #%d: Matrix expected.\n"), "corr" , 2);
215                 return types::Function::Error;
216             }
217
218             pDblY = in[1]->getAs<types::Double>();
219
220             if (in[0]->isDouble() == false)
221             {
222                 Scierror(999, _("%s: Wrong type for input argument #%d: Matrix expected.\n"), "corr" , 1);
223                 return types::Function::Error;
224             }
225
226             pDblX = in[0]->getAs<types::Double>();
227
228             if (pDblX->getSize() != pDblY->getSize())
229             {
230                 Scierror(60, _("%s: Wrong size for argument: Incompatible dimensions.\n"), "corr");
231                 return types::Function::Error;
232             }
233         }
234         else
235         {
236             if (in[0]->isDouble() == false)
237             {
238                 Scierror(999, _("%s: Wrong type for input argument #%d: Matrix expected.\n"), "corr" , 1);
239                 return types::Function::Error;
240             }
241
242             pDblX = in[0]->getAs<types::Double>();
243             pDblY = pDblX;
244         }
245
246         iSize = pDblX->getSize();
247         pDblCorrelation = new types::Double(1, iCorrelation);
248         C2F(tscccf)(pDblX->get(), pDblY->get(), &iSize, pDblCorrelation->get(), pdblMean, &iCorrelation, &iErr);
249         if (iErr == -1)
250         {
251             delete pDblCorrelation;
252             Scierror(999, _("%s: Too many coefficients are required.\n"), "corr");
253             return types::Function::Error;
254         }
255
256         out.push_back(pDblCorrelation);
257
258         if (_iRetCount == 2)
259         {
260             if (in.size() == 3)
261             {
262                 pDblMean = new types::Double(1, 2);
263             }
264             else
265             {
266                 pDblMean = new types::Double(1, 1);
267             }
268
269             pDblMean->set(pdblMean);
270             out.push_back(pDblMean);
271         }
272     }
273
274     return types::Function::OK;
275 }
276