Coverity Fix #1321326 and #1321325: Memory Leak Resolved
[scilab.git] / scilab / modules / randlib / sci_gateway / cpp / sci_grand.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - DIGITEO - Cedric DELAMARRE
4 * Copyright (C) 2014 - Scilab Enterprises - Sylvain GENIN
5 *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14 *
15 */
16 /*--------------------------------------------------------------------------*/
17 #include "randlib_gw.hxx"
18 #include "function.hxx"
19 #include "double.hxx"
20 #include "string.hxx"
21 #include "configvariable.hxx"
22 #include "int.hxx"
23 #include "polynom.hxx"
24 #include "sparse.hxx"
25 #include "overload.hxx"
26
27 extern "C"
28 {
29 #include "sci_malloc.h"
30 #include "localization.h"
31 #include "Scierror.h"
32 #include "sciprint.h"
33 #include "grand.h"
34 #include "clcg4.h"
35 #include "others_generators.h"
36 }
37 /*--------------------------------------------------------------------------*/
38
39 template<class U>
40 void sci_grand_prm(int iNumIter, U *pIn, types::InternalType** pOut);
41
42 types::Function::ReturnValue sci_grand(types::typed_list &in, int _iRetCount, types::typed_list &out)
43 {
44     enum
45     {
46         MT, KISS, CLCG4, CLCG2, URAND, FSULTRA
47     };
48
49     //  names at the scilab level
50     const wchar_t* names_gen[6] = { L"mt", L"kiss", L"clcg4", L"clcg2", L"urand", L"fsultra" };
51
52     types::String* pStrMethod = NULL;
53     types::String* pStrGenOrPhr = NULL;
54
55     std::vector<types::Double*> vectpDblInput;
56
57     int iStrPos = 0;
58     int iPos = 0;
59     int meth = -1;
60     int iRows = -1;
61     int iCols = -1;
62     int iNumIter = -1;
63
64
65     int current_base_gen = ConfigVariable::getCurrentBaseGen();
66
67     // *** check the maximal number of input args. ***
68     /* if (in.size() > 6)
69     {
70     Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "grand", 1, 6);
71     return types::Function::Error;
72     }*/
73
74     // *** check number of output args. ***
75     if (_iRetCount > 1)
76     {
77         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "grand", 1);
78         return types::Function::Error;
79     }
80
81     // *** find the method string. ***
82     for (int i = 0; i < in.size(); i++)
83     {
84         if (in[i]->isString())
85         {
86             pStrMethod = in[i]->getAs<types::String>();
87             iStrPos = i;
88             break;
89         }
90     }
91
92     if (pStrMethod == NULL)
93     {
94         for (int i = 0; i < in.size(); i++)
95         {
96             if (in[i]->isDouble() == false)
97             {
98                 std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_grand";
99                 return Overload::call(wstFuncName, in, _iRetCount, out);
100             }
101         }
102
103         Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "grand", in.size() + 1);
104         return types::Function::Error;
105     }
106
107     int iDims = iStrPos > 1 ? iStrPos : 2;
108     int *itab = new int[iDims];
109
110     //all variables are matrix
111     itab[0] = 1;
112     itab[1] = 1;
113
114     wchar_t* wcsMeth = pStrMethod->get(0);
115     int iNumInputArg = 5;
116     if (wcscmp(wcsMeth, L"bet") == 0) // beta
117     {
118         meth = 1;
119     }
120     else if (wcscmp(wcsMeth, L"bin") == 0) // binomial
121     {
122         meth = 2;
123     }
124     else if (wcscmp(wcsMeth, L"nbn") == 0) // negative binomial
125     {
126         meth = 3;
127     }
128     else if (wcscmp(wcsMeth, L"chi") == 0) // chisquare
129     {
130         iNumInputArg = 4;
131         meth = 4;
132     }
133     else if (wcscmp(wcsMeth, L"nch") == 0) // non central chisquare
134     {
135         meth = 5;
136     }
137     else if (wcscmp(wcsMeth, L"exp") == 0) // exponential
138     {
139         iNumInputArg = 4;
140         meth = 6;
141     }
142     else if (wcscmp(wcsMeth, L"f") == 0) // F variance ratio
143     {
144         meth = 7;
145     }
146     else if (wcscmp(wcsMeth, L"nf") == 0) // non central F variance ratio
147     {
148         iNumInputArg = 6;
149         meth = 8;
150     }
151     else if (wcscmp(wcsMeth, L"gam") == 0) // gamma
152     {
153         meth = 9;
154     }
155     else if (wcscmp(wcsMeth, L"nor") == 0) // Gauss Laplace (normal)
156     {
157         meth = 10;
158     }
159     else if (wcscmp(wcsMeth, L"mn") == 0) // multivariate gaussian (multivariate normal)
160     {
161         iNumInputArg = 4;
162         meth = 11;
163     }
164     else if (wcscmp(wcsMeth, L"geom") == 0) // geometric
165     {
166         iNumInputArg = 4;
167         meth = 12;
168     }
169     else if (wcscmp(wcsMeth, L"markov") == 0) // markov
170     {
171         iNumInputArg = 4;
172         meth = 13;
173     }
174     else if (wcscmp(wcsMeth, L"mul") == 0) // multinomial
175     {
176         iNumInputArg = 4;
177         meth = 14;
178     }
179     else if (wcscmp(wcsMeth, L"poi") == 0) // Poisson
180     {
181         iNumInputArg = 4;
182         meth = 15;
183     }
184     else if (wcscmp(wcsMeth, L"prm") == 0) // random permutations
185     {
186         iNumInputArg = 3;
187         meth = 16;
188     }
189     else if (wcscmp(wcsMeth, L"def") == 0) // uniform (def)
190     {
191         iNumInputArg = 3;
192         meth = 17;
193     }
194     else if (wcscmp(wcsMeth, L"unf") == 0) // uniform (unf)
195     {
196         meth = 18;
197     }
198     else if (wcscmp(wcsMeth, L"uin") == 0) // uniform (uin)
199     {
200         meth = 19;
201     }
202     else if (wcscmp(wcsMeth, L"lgi") == 0) // uniform (lgi)
203     {
204         iNumInputArg = 3;
205         meth = 20;
206     }
207     else if (wcscmp(wcsMeth, L"getgen") == 0) // getgen
208     {
209         iNumInputArg = 1;
210         meth = 21;
211     }
212     else if (wcscmp(wcsMeth, L"setgen") == 0) // setgen
213     {
214         iNumInputArg = 2;
215         meth = 22;
216     }
217     else if (wcscmp(wcsMeth, L"getsd") == 0) // getsd
218     {
219         iNumInputArg = 1;
220         meth = 23;
221     }
222     else if (wcscmp(wcsMeth, L"setsd") == 0) // setsd
223     {
224         switch (current_base_gen)
225         {
226             case MT:
227                 iNumInputArg = 2;
228                 break;
229             case KISS:
230                 iNumInputArg = 5;
231                 break;
232             case CLCG2:
233                 iNumInputArg = 3;
234                 break;
235             case CLCG4:
236                 iNumInputArg = 5;
237                 break;
238             case URAND:
239                 iNumInputArg = 2;
240                 break;
241             case FSULTRA:
242             {
243                 if (in.size() != 2 && in.size() != 3)
244                 {
245                     char* pstMeth = wide_string_to_UTF8(wcsMeth);
246                     Scierror(77, _("%s: Wrong number of input argument(s) for method %s: %d or %d expected.\n"), "grand", pstMeth, 2, 3);
247                     FREE(pstMeth);
248                     delete[] itab;
249                     return types::Function::Error;
250                 }
251
252                 iNumInputArg = (int)in.size();
253                 break;
254             }
255         }
256         meth = 24;
257     }
258     else if (wcscmp(wcsMeth, L"phr2sd") == 0) // phr2sd
259     {
260         iNumInputArg = 2;
261         meth = 25;
262     }
263     else if (wcscmp(wcsMeth, L"setcgn") == 0) // setcgn
264     {
265         iNumInputArg = 2;
266         meth = 26;
267     }
268     else if (wcscmp(wcsMeth, L"getcgn") == 0) // getcgn
269     {
270         iNumInputArg = 1;
271         meth = 27;
272     }
273     else if (wcscmp(wcsMeth, L"initgn") == 0) // initgn
274     {
275         iNumInputArg = 2;
276         meth = 28;
277     }
278     else if (wcscmp(wcsMeth, L"setall") == 0) // setall
279     {
280         iNumInputArg = 5;
281         meth = 29;
282     }
283     else if (wcscmp(wcsMeth, L"advnst") == 0) // advnst
284     {
285         iNumInputArg = 2;
286         meth = 30;
287     }
288     else
289     {
290         char* pstMeth = wide_string_to_UTF8(wcsMeth);
291         Scierror(78, _("%s: Wrong method for input argument #%d: %s unknown.\n"), "grand", iStrPos + 1, pstMeth);
292         FREE(pstMeth);
293         delete[] itab;
294         return types::Function::Error;
295     }
296
297     // *** get arguments before methode string. ***
298     if (meth == 11 || meth == 13 || meth == 14 || meth == 16) // grand(n, "...", ...
299     {
300         if (iStrPos != 1)
301         {
302             Scierror(999, _("%s: Wrong position for input argument #%d : Must be in position %d.\n"), "grand", iStrPos + 1, 2);
303             delete[] itab;
304             return types::Function::Error;
305         }
306
307         if (in[iPos]->isDouble() == false)
308         {
309             Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "grand", iPos + 1);
310             delete[] itab;
311             return types::Function::Error;
312         }
313
314         types::Double* pDblTemp = in[iPos]->getAs<types::Double>();
315
316         if (pDblTemp->isScalar() == false)
317         {
318             Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", iPos + 1);
319             delete[] itab;
320             return types::Function::Error;
321         }
322
323         iNumIter = (int)pDblTemp->get(0);
324         iPos++;
325     }
326     else if (meth < 21) // grand(m, n, "...", ... || grand(matrix, "...", ...
327     {
328
329         /*if (iStrPos != 1 && iStrPos != 2)
330         {
331         Scierror(999, _("%s: Wrong position for input argument #%d : Must be in position %d or %d.\n"), "grand", iStrPos + 1, 2, 3);
332         return types::Function::Error;
333         }*/
334
335         std::vector<types::Double*> vectpDblTemp;
336         for (int i = 0; i < iStrPos; i++)
337         {
338             if (in[iPos]->isDouble() == false)
339             {
340                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", iPos + 1);
341                 delete[] itab;
342                 return types::Function::Error;
343             }
344
345             vectpDblTemp.push_back(in[iPos]->getAs<types::Double>());
346
347             if (iStrPos == 3 && vectpDblTemp[i]->isScalar() == false)
348             {
349                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", iPos + 1);
350                 delete[] itab;
351                 return types::Function::Error;
352             }
353             iPos++;
354         }
355
356         //get number of dimensions to output
357         for (int i = 0; i < iStrPos; i++)
358         {
359             itab[i] = static_cast<int>(vectpDblTemp[i]->get(0));
360         }
361     }
362
363     if (in[iPos]->isString() == false)
364     {
365         Scierror(999, _("%s: Wrong type for input argument #%d : string expected.\n"), "grand", iPos + 1);
366         delete[] itab;
367         return types::Function::Error;
368     }
369     iPos++; // method string has been already got.
370
371     // *** get arguments after methode string. ***
372     if (meth == 22 || meth == 25) // setgen || phr2sd
373     {
374         if (in[iPos]->isString() == false)
375         {
376             Scierror(999, _("%s: Wrong type for input argument #%d : string expected.\n"), "grand", iPos + 1);
377             delete[] itab;
378             return types::Function::Error;
379         }
380
381         pStrGenOrPhr = in[iPos]->getAs<types::String>();
382
383         if (pStrGenOrPhr->isScalar() == false)
384         {
385             Scierror(999, _("%s: Wrong size for input argument #%d : Only one string expected.\n"), "grand", iPos + 1);
386             delete[] itab;
387             return types::Function::Error;
388         }
389     }
390     else if (meth == 16)
391     {
392         if (in.size() > 3)
393         {
394             Scierror(999, _("Missing vect for random permutation\n"));
395             delete[] itab;
396             return types::Function::Error;
397         }
398     }
399     else
400     {
401
402         for (int i = iPos; i < in.size(); i++)
403         {
404             if (in[i]->isDouble() == false)
405             {
406                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", iPos + 1);
407                 delete[] itab;
408                 return types::Function::Error;
409             }
410
411             vectpDblInput.push_back(in[i]->getAs<types::Double>());
412         }
413     }
414
415     // *** perform operation in according method string and return result. ***
416
417     types::Double* pDblOut = NULL;
418
419     if (iStrPos >= 2)
420     {
421         int iProdiTab = 1;
422         for (int i = 0; i < iStrPos; i++)
423         {
424             iProdiTab = iProdiTab * itab[i];
425         }
426
427         if (iProdiTab == 0)
428         {
429             pDblOut = types::Double::Empty();
430         }
431         else if ((itab[1] != itab[0]) && (itab[0] <= -1))
432         {
433             Scierror(999, _("%s: Wrong value for input argument #%d: Positive scalar expected.\n"), "grand", 1);
434             delete[] itab;
435             return types::Function::Error;
436         }
437         else if ((itab[1] != itab[0]) && (itab[1] <= -1))
438         {
439             Scierror(999, _("%s: Wrong value for input argument #%d: Positive scalar expected.\n"), "grand", 2);
440             delete[] itab;
441             return types::Function::Error;
442         }
443         else
444         {
445             pDblOut = new types::Double(iDims, itab);
446         }
447     }
448     else
449     {
450
451         types::Double* pDblIn = in[0]->getAs<types::Double>();
452         if (meth == 14)//'mul'
453         {
454             int* iDimsArraytempo = new int[2];
455             iDimsArraytempo[0] = in[3]->getAs<types::Double>()->getSize() + 1;
456             iDimsArraytempo[1] = iNumIter;
457             pDblOut = new types::Double(pDblIn->getDims(), iDimsArraytempo);
458         }
459         else
460         {
461             pDblOut = new types::Double(pDblIn->getDims(), pDblIn->getDimsArray());
462         }
463
464     }
465
466     delete[] itab;
467
468     switch (meth)
469     {
470         case 1: // beta
471         {
472             double minlog   = 1.e-37;
473
474             for (int i = 0; i < 2; i++)
475             {
476                 if (vectpDblInput[i]->isScalar() == false)
477                 {
478                     delete pDblOut;
479                     Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 4);
480                     return types::Function::Error;
481                 }
482
483                 if (vectpDblInput[i]->get(0) < minlog)
484                 {
485                     delete pDblOut;
486                     Scierror(999, _("%s: Wrong value for input argument #%d : At least %lf expected.\n"), "grand", iPos + 1, minlog);
487                     return types::Function::Error;
488                 }
489             }
490
491             for (int i = 0; i < pDblOut->getSize(); i++)
492             {
493                 pDblOut->set(i, C2F(genbet)(vectpDblInput[0]->get(), vectpDblInput[1]->get()));
494             }
495
496             out.push_back(pDblOut);
497             break;
498         }
499         case 2: // binomial
500         case 3: // negative binomial
501         {
502             for (int i = 0; i < 2; i++)
503             {
504                 if (vectpDblInput[i]->isScalar() == false)
505                 {
506                     delete pDblOut;
507                     Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 4);
508                     return types::Function::Error;
509                 }
510             }
511
512             if (vectpDblInput[0]->get(0) < 0.0) // N
513             {
514                 delete pDblOut;
515                 Scierror(999, _("%s: Wrong value for input argument #%d : Positive integer expected.\n"), "grand", 4);
516                 return types::Function::Error;
517             }
518
519             if (vectpDblInput[1]->get(0) < 0.0 || vectpDblInput[1]->get(0) > 1.0) // p
520             {
521                 delete pDblOut;
522                 Scierror(999, _("%s: Wrong value for input argument #%d : A value expected.\n"), "grand", 5);
523                 return types::Function::Error;
524             }
525
526             int N = static_cast<int>(vectpDblInput[0]->get(0));
527             if (meth == 2)
528             {
529                 for (int i = 0; i < pDblOut->getSize(); i++)
530                 {
531                     pDblOut->set(i, static_cast<double>(C2F(ignbin)(&N, vectpDblInput[1]->get())));
532                 }
533             }
534             else // meth == 3
535             {
536                 for (int i = 0; i < pDblOut->getSize(); i++)
537                 {
538                     pDblOut->set(i, static_cast<double>(C2F(ignnbn)(&N, vectpDblInput[1]->get())));
539                 }
540             }
541
542             out.push_back(pDblOut);
543             break;
544         }
545         case 4: // chisquare
546         {
547             if (vectpDblInput[0]->isScalar() == false)
548             {
549                 delete pDblOut;
550                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", 4);
551                 return types::Function::Error;
552             }
553
554             if (vectpDblInput[0]->get(0) <= 0.0) // Df
555             {
556                 delete pDblOut;
557                 Scierror(999, _("%s: Wrong value for input argument #%d : Positive no null value expected.\n"), "grand", 4);
558                 return types::Function::Error;
559             }
560
561             for (int i = 0; i < pDblOut->getSize(); i++)
562             {
563                 pDblOut->set(i, C2F(genchi)(vectpDblInput[0]->get()));
564             }
565
566             out.push_back(pDblOut);
567             break;
568         }
569         case 5: // non central chisquare
570         {
571             for (int i = 0; i < 2; i++)
572             {
573                 if (vectpDblInput[i]->isScalar() == false)
574                 {
575                     delete pDblOut;
576                     Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 4);
577                     return types::Function::Error;
578                 }
579             }
580
581             if (vectpDblInput[0]->get(0) < 1.0) // Df
582             {
583                 delete pDblOut;
584                 Scierror(999, _("%s: Wrong value for input argument #%d : value > 1.0 expected.\n"), "grand", 4);
585                 return types::Function::Error;
586             }
587
588             if (vectpDblInput[1]->get(0) < 0.0) // Xnon
589             {
590                 delete pDblOut;
591                 Scierror(999, _("%s: Wrong value for input argument #%d : Positive value expected.\n"), "grand", 5);
592                 return types::Function::Error;
593             }
594
595             for (int i = 0; i < pDblOut->getSize(); i++)
596             {
597                 pDblOut->set(i, C2F(gennch)(vectpDblInput[0]->get(), vectpDblInput[1]->get()));
598             }
599
600             out.push_back(pDblOut);
601             break;
602         }
603         case 6: // exponential
604         {
605             if (vectpDblInput[0]->isScalar() == false)
606             {
607                 delete pDblOut;
608                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", 4);
609                 return types::Function::Error;
610             }
611
612             if (vectpDblInput[0]->get(0) < 0.0) // Av
613             {
614                 delete pDblOut;
615                 Scierror(999, _("%s: Wrong value for input argument #%d : Positive value expected.\n"), "grand", 4);
616                 return types::Function::Error;
617             }
618
619             for (int i = 0; i < pDblOut->getSize(); i++)
620             {
621                 pDblOut->set(i, C2F(genexp)(vectpDblInput[0]->get()));
622             }
623
624             out.push_back(pDblOut);
625             break;
626         }
627         case 7: // F variance ratio
628         {
629             for (int i = 0; i < 2; i++)
630             {
631                 if (vectpDblInput[i]->isScalar() == false)
632                 {
633                     delete pDblOut;
634                     Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 4);
635                     return types::Function::Error;
636                 }
637
638                 if (vectpDblInput[i]->get(0) <= 0.0) // Dfn Dfd
639                 {
640                     delete pDblOut;
641                     Scierror(999, _("%s: Wrong value for input argument #%d : Positive no null value expected.\n"), "grand", i + 4);
642                     return types::Function::Error;
643                 }
644             }
645
646             for (int i = 0; i < pDblOut->getSize(); i++)
647             {
648                 pDblOut->set(i, C2F(genf)(vectpDblInput[0]->get(), vectpDblInput[1]->get()));
649             }
650
651             out.push_back(pDblOut);
652             break;
653         }
654         case 8: // non F variance ratio
655         {
656             for (int i = 0; i < 3; i++)
657             {
658                 if (vectpDblInput[i]->isScalar() == false)
659                 {
660                     delete pDblOut;
661                     Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 4);
662                     return types::Function::Error;
663                 }
664             }
665
666             if (vectpDblInput[0]->get(0) < 1.0) // Dfn
667             {
668                 delete pDblOut;
669                 Scierror(999, _("%s: Wrong value for input argument #%d : value > 1.0 expected.\n"), "grand", 4);
670                 return types::Function::Error;
671             }
672
673             if (vectpDblInput[1]->get(0) <= 0.0) // Dfd
674             {
675                 delete pDblOut;
676                 Scierror(999, _("%s: Wrong value for input argument #%d : Positive non null value expected.\n"), "grand", 5);
677                 return types::Function::Error;
678             }
679
680             if (vectpDblInput[2]->get(0) < 0.0) // Xnon
681             {
682                 delete pDblOut;
683                 Scierror(999, _("%s: Wrong value for input argument #%d : Positive value expected.\n"), "grand", 6);
684                 return types::Function::Error;
685             }
686
687             for (int i = 0; i < pDblOut->getSize(); i++)
688             {
689                 pDblOut->set(i, C2F(gennf)(vectpDblInput[0]->get(), vectpDblInput[1]->get(), vectpDblInput[2]->get()));
690             }
691
692             out.push_back(pDblOut);
693             break;
694         }
695         case 9: // gamma
696         {
697             for (int i = 0; i < 2; i++)
698             {
699                 if (vectpDblInput[i]->isScalar() == false)
700                 {
701                     delete pDblOut;
702                     Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 4);
703                     return types::Function::Error;
704                 }
705
706                 if (vectpDblInput[i]->get(0) <= 0.0)
707                 {
708                     delete pDblOut;
709                     Scierror(999, _("%s: Wrong value for input argument #%d : Positive non null value expected.\n"), "grand", i + 4);
710                     return types::Function::Error;
711                 }
712             }
713
714             for (int i = 0; i < pDblOut->getSize(); i++)
715             {
716                 //** WARNING ** : order is changed in parameters for
717                 //compatibility between Rand(...'gam',..) and cdfgam
718
719                 pDblOut->set(i, C2F(gengam)(vectpDblInput[1]->get(), vectpDblInput[0]->get()));
720             }
721
722             out.push_back(pDblOut);
723             break;
724         }
725         case 10: // Gauss Laplace (normal)
726         {
727             for (int i = 0; i < 2; i++)
728             {
729                 if (vectpDblInput[i]->isScalar() == false)
730                 {
731                     delete pDblOut;
732                     Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 4);
733                     return types::Function::Error;
734                 }
735             }
736
737             if (vectpDblInput[1]->get(0) < 0.0)
738             {
739                 delete pDblOut;
740                 Scierror(999, _("%s: Wrong value for input argument #%d : Positive value expected.\n"), "grand", 5);
741                 return types::Function::Error;
742             }
743
744             for (int i = 0; i < pDblOut->getSize(); i++)
745             {
746                 pDblOut->set(i, C2F(gennor)(vectpDblInput[0]->get(), vectpDblInput[1]->get()));
747             }
748
749             out.push_back(pDblOut);
750             break;
751         }
752         case 11: // multivariate gaussian (multivariate normal)
753         {
754             if (vectpDblInput[0]->getCols() != 1 || vectpDblInput[0]->getSize() == 0)
755             {
756                 delete pDblOut;
757                 Scierror(999, _("%s: Wrong size for input argument #%d : A matrix of size m x 1 expected.(m > 0)\n"), "grand", 4);
758                 return types::Function::Error;
759             }
760
761             if (vectpDblInput[0]->getRows() != vectpDblInput[1]->getRows())
762             {
763                 delete pDblOut;
764                 Scierror(999, _("%s: Wrong size for input arguments #%d and #%d: Mean and Cov have incompatible dimensions.\n"), "grand", 4, 5);
765                 return types::Function::Error;
766             }
767
768             if (vectpDblInput[1]->getRows() != vectpDblInput[1]->getCols())
769             {
770                 delete pDblOut;
771                 Scierror(999, _("%s: Wrong size for input argument #%d : A square symmetric positive definite matrix expected.\n"), "grand", 5);
772                 return types::Function::Error;
773             }
774
775             int ierr = 0;
776             int size = vectpDblInput[0]->getRows();
777             int mp   = (size * (size + 3)) / 2 + 1;
778
779             delete pDblOut;
780             types::Double* pDblOut = new types::Double(size, iNumIter);
781             double* work = new double[size];
782             double* param = new double[mp];
783
784             types::Double* pDblMean = vectpDblInput[0]->clone()->getAs<types::Double>();
785             types::Double* pDblCov  = vectpDblInput[1]->clone()->getAs<types::Double>();
786
787             C2F(setgmn)(pDblMean->get(), pDblCov->get(), &size, &size, param, &ierr);
788
789             delete pDblMean;
790             delete pDblCov;
791
792             if (ierr == 1)
793             {
794                 delete[] work;
795                 delete[] param;
796                 delete pDblOut;
797                 Scierror(999, _("%s: setgmn return with state %d.\n"), "grand", ierr);
798                 return types::Function::Error;
799             }
800
801             for (int i = 0; i < iNumIter; i++)
802             {
803                 C2F(genmn)(param, pDblOut->get() + (size * i), work);
804             }
805
806             delete[] work;
807             delete[] param;
808
809             out.push_back(pDblOut);
810             break;
811         }
812         case 12: // geometric
813         {
814             double pmin = 1.3e-307;
815
816             if (vectpDblInput[0]->isScalar() == false)
817             {
818                 delete pDblOut;
819                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", 4);
820                 return types::Function::Error;
821             }
822
823             if (vectpDblInput[0]->get(0) < pmin || vectpDblInput[0]->get(0) > 1.0)
824             {
825                 delete pDblOut;
826                 Scierror(999, _("%s: Wrong value for input argument #%d : Must be between %lf and %d.\n"), "grand", 4, pmin, 1);
827                 return types::Function::Error;
828             }
829
830             for (int i = 0; i < pDblOut->getSize(); i++)
831             {
832                 pDblOut->set(i, igngeom(vectpDblInput[0]->get(0)));
833             }
834
835             out.push_back(pDblOut);
836             break;
837         }
838         case 13: // markov
839         {
840             if ( vectpDblInput[0]->getRows() != vectpDblInput[0]->getCols() &&
841                     vectpDblInput[0]->getRows() != 1)
842             {
843                 delete pDblOut;
844                 Scierror(999, _("%s: Wrong size for input argument #%d : A square matrix or a row vector expected.\n"), "grand", 4);
845                 return types::Function::Error;
846             }
847
848             if (vectpDblInput[1]->getSize() == 0)
849             {
850                 delete pDblOut;
851                 Scierror(999, _("%s: Wrong size for input argument #%d: No empty matrix expected.\n"), "grand", 5);
852                 return types::Function::Error;
853             }
854
855             int sizeOfX0 = vectpDblInput[1]->getSize();
856
857             for ( int i = 0; i < sizeOfX0; i++)
858             {
859                 if (vectpDblInput[1]->get(i) < 1 || (vectpDblInput[1]->get(i) - 1) >= vectpDblInput[0]->getCols())
860                 {
861                     Scierror(999, _("%s: X0(%d) must be in the range [1,%d[.\n"), "grand", i + 1, vectpDblInput[0]->getCols() + 1);
862                     return types::Function::Error;
863                 }
864             }
865
866             int size = vectpDblInput[0]->getSize() + vectpDblInput[0]->getCols();
867             double* work = new double[(size * sizeof(double))];
868
869             for (int i = 0; i < vectpDblInput[0]->getRows(); i++)
870             {
871                 double ptot = 0.0;
872                 for (int j = 0; j < vectpDblInput[0]->getCols(); j++)
873                 {
874                     int position = vectpDblInput[0]->getRows() * j + i;
875
876                     if (vectpDblInput[0]->get(position) < 0 || vectpDblInput[0]->get(position) > 1)
877                     {
878                         delete pDblOut;
879                         Scierror(999, _("%s: Wrong value for input argument #%d: P(%d,%d) must be in the range [0 1].\n"), "grand", i + 1, j + 1);
880                         delete[] work;
881                         return types::Function::Error;
882                     }
883
884                     ptot += vectpDblInput[0]->get(position);
885                 }
886
887                 if (fabs(ptot - 1.0) > 1e-8)
888                 {
889                     delete pDblOut;
890                     Scierror(999, _("%s: Sum of P(%d,1:%d)=%lf ~= 1.\n"), "grand", i + 1, vectpDblInput[0]->getCols(), ptot);
891                     delete[] work;
892                     return types::Function::Error;
893                 }
894             }
895             // ** Computing the cumulative sum of the P matrix **
896
897             for (int i = 0; i < vectpDblInput[0]->getRows(); i++)
898             {
899                 double cumsum = 0.0;
900                 work[i] = 0.0;
901                 for (int j = 1; j < vectpDblInput[0]->getCols() + 1; j++)
902                 {
903                     cumsum += vectpDblInput[0]->get(vectpDblInput[0]->getRows() * (j - 1) + i);
904                     work[vectpDblInput[0]->getRows() * j + i] = cumsum;
905                 }
906             }
907
908             for (int i = 0; i < vectpDblInput[1]->getSize(); i++)
909             {
910                 int iCur = static_cast<int>(vectpDblInput[1]->get(i)) - 1;
911                 for (int j = 0; j < iNumIter; j++)
912                 {
913                     int niv = 0;
914                     double rr = C2F(ranf)();
915
916                     if (vectpDblInput[0]->getRows() == 1)
917                     {
918                         iCur = 0;
919                     }
920
921                     while (  rr >= work[iCur + vectpDblInput[0]->getRows() * niv] &&
922                              niv < (vectpDblInput[0]->getRows() + 1))
923                     {
924                         niv++;
925                     }
926
927                     // ** projection to avoid boundaries **
928                     niv = std::max(std::min(niv, vectpDblInput[0]->getCols()), 1);
929                     pDblOut->set(vectpDblInput[1]->getSize() * j + i, static_cast<double>(niv));
930                     iCur = niv - 1;
931                 }
932             }
933
934             out.push_back(pDblOut);
935             delete[] work;
936             break;
937         }
938         case 14: // multinomial
939         {
940             if (vectpDblInput[0]->isScalar() == false)
941             {
942                 delete pDblOut;
943                 Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), "grand", 4);
944                 return types::Function::Error;
945             }
946
947             if (vectpDblInput[0]->get(0) < 0)
948             {
949                 delete pDblOut;
950                 Scierror(999, _("%s: Wrong value for input argument #%d: A positive scalar expected.\n"), "grand", 4);
951                 return types::Function::Error;
952             }
953
954             if (vectpDblInput[1]->getCols() != 1 || vectpDblInput[1]->getRows() <= 0)
955             {
956                 delete pDblOut;
957                 Scierror(999, _("%s: Wrong size for input argument #%d: A column vector expected.\n"), "grand", 5);
958                 return types::Function::Error;
959             }
960
961             double ptot = 0.0;
962             int ncat = vectpDblInput[1]->getRows() + 1;
963
964             for (int i = 0; i < vectpDblInput[1]->getCols(); i++)
965             {
966                 if (vectpDblInput[1]->get(i) < 0.0 || vectpDblInput[1]->get(i) > 1.0)
967                 {
968                     delete pDblOut;
969                     Scierror(999, _("%s: Wrong value for input argument #%d: P(%d) must be in the range [0 1].\n"), "grand", 5, i + 1);
970                     return types::Function::Error;
971                 }
972                 ptot += vectpDblInput[1]->get(i);
973             }
974
975             if (ptot > 1.0)
976             {
977                 delete pDblOut;
978                 Scierror(999, _("%s: Wrong value for input argument #%d: Sum of P(i) > 1.\n"), "grand", 5);
979                 return types::Function::Error;
980             }
981
982             int* piP = new int[vectpDblInput[0]->getSize()];
983             int* piOut = new int[pDblOut->getSize()];
984
985             for (int i = 0; i < vectpDblInput[0]->getSize(); i++)
986             {
987                 piP[i] = static_cast<int>(vectpDblInput[0]->get(i));
988             }
989
990             for (int i = 0; i < iNumIter; i++)
991             {
992                 C2F(genmul)(piP, vectpDblInput[1]->get(), &ncat,  + &piOut[ncat * i]);
993             }
994
995             for (int i = 0; i < pDblOut->getSize(); i++)
996             {
997                 pDblOut->set(i, static_cast<double>(piOut[i]));
998             }
999
1000             delete piP;
1001             delete piOut;
1002
1003             out.push_back(pDblOut);
1004             break;
1005         }
1006         case 15: // Poisson
1007         {
1008             if (vectpDblInput[0]->isScalar() == false)
1009             {
1010                 delete pDblOut;
1011                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", 4);
1012                 return types::Function::Error;
1013             }
1014
1015             if (vectpDblInput[0]->get(0) < 0.0)
1016             {
1017                 delete pDblOut;
1018                 Scierror(999, _("%s: Wrong value for input argument #%d : Positive value expected.\n"), "grand", 4);
1019                 return types::Function::Error;
1020             }
1021
1022             for (int i = 0; i < pDblOut->getSize(); i++)
1023             {
1024                 pDblOut->set(i, static_cast<double>(C2F(ignpoi)(vectpDblInput[0]->get())));
1025             }
1026
1027             out.push_back(pDblOut);
1028             break;
1029         }
1030         case 16: // random permutations
1031         {
1032             delete pDblOut;
1033             types::InternalType* pITOut = NULL;
1034
1035             // get dims and isComplex
1036             int iDims = 0;
1037             int* piDimsArray = NULL;
1038             bool bIsComplex = false;
1039             if (in[2]->isGenericType())
1040             {
1041                 types::GenericType* pGT = in[2]->getAs<types::GenericType>();
1042                 iDims = pGT->getDims();
1043                 piDimsArray = pGT->getDimsArray();
1044                 bIsComplex = pGT->isComplex();
1045             }
1046
1047             switch (in[2]->getType())
1048             {
1049                 case types::InternalType::ScilabInt8:
1050                     pITOut = new types::Int8(iDims, piDimsArray);
1051                     sci_grand_prm(iNumIter, in[2]->getAs<types::Int8>(), &pITOut);
1052                     break;
1053                 case types::InternalType::ScilabUInt8:
1054                     pITOut = new types::UInt8(iDims, piDimsArray);
1055                     sci_grand_prm(iNumIter, in[2]->getAs<types::UInt8>(), &pITOut);
1056                     break;
1057                 case types::InternalType::ScilabInt16:
1058                     pITOut = new types::Int16(iDims, piDimsArray);
1059                     sci_grand_prm(iNumIter, in[2]->getAs<types::Int16>(), &pITOut);
1060                     break;
1061                 case types::InternalType::ScilabUInt16:
1062                     pITOut = new types::UInt16(iDims, piDimsArray);
1063                     sci_grand_prm(iNumIter, in[2]->getAs<types::UInt16>(), &pITOut);
1064                     break;
1065                 case types::InternalType::ScilabInt32:
1066                     pITOut = new types::Int32(iDims, piDimsArray);
1067                     sci_grand_prm(iNumIter, in[2]->getAs<types::Int32>(), &pITOut);
1068                     break;
1069                 case types::InternalType::ScilabUInt32:
1070                     pITOut = new types::UInt32(iDims, piDimsArray);
1071                     sci_grand_prm(iNumIter, in[2]->getAs<types::UInt32>(), &pITOut);
1072                     break;
1073                 case types::InternalType::ScilabInt64:
1074                     pITOut = new types::Int64(iDims, piDimsArray);
1075                     sci_grand_prm(iNumIter, in[2]->getAs<types::Int64>(), &pITOut);
1076                     break;
1077                 case types::InternalType::ScilabUInt64:
1078                     pITOut = new types::UInt64(iDims, piDimsArray);
1079                     sci_grand_prm(iNumIter, in[2]->getAs<types::UInt64>(), &pITOut);
1080                     break;
1081                 case types::InternalType::ScilabDouble:
1082                     pITOut = new types::Double(iDims, piDimsArray, bIsComplex);
1083                     sci_grand_prm(iNumIter, in[2]->getAs<types::Double>(), &pITOut);
1084                     break;
1085                 case types::InternalType::ScilabBool:
1086                     pITOut = new types::Bool(iDims, piDimsArray);
1087                     sci_grand_prm(iNumIter, in[2]->getAs<types::Bool>(), &pITOut);
1088                     break;
1089                 case types::InternalType::ScilabString:
1090                     pITOut = new types::String(iDims, piDimsArray);
1091                     sci_grand_prm(iNumIter, in[2]->getAs<types::String>(), &pITOut);
1092                     break;
1093                 case types::InternalType::ScilabPolynom:
1094                     pITOut = new types::Polynom(in[2]->getAs<types::Polynom>()->getVariableName(), iDims, piDimsArray);
1095                     sci_grand_prm(iNumIter, in[2]->getAs<types::Polynom>(), &pITOut);
1096                     break;
1097                 case types::InternalType::ScilabSparse:
1098                 {
1099                     std::complex<double> cplxDbl;
1100                     types::InternalType* pITOutTempo = NULL;
1101                     types::Double* pDblTempo = NULL;
1102                     types::Sparse* pSP = in[2]->getAs<types::Sparse>();
1103                     int isize = pSP->getSize();
1104                     pITOut = new types::Sparse(pSP->getRows(), pSP->getCols(), pSP->isComplex());
1105                     pDblTempo = new types::Double(isize, 1, pSP->isComplex());
1106                     pITOutTempo = new types::Double(isize, iNumIter, pSP->isComplex());
1107
1108                     if (pDblTempo->isComplex())
1109                     {
1110                         for (int i = 0; i < isize; i++)
1111                         {
1112                             cplxDbl = in[2]->getAs<types::Sparse>()->getImg(i);
1113                             pDblTempo->set(i, cplxDbl.real());
1114                             pDblTempo->set(i, cplxDbl.imag());
1115                         }
1116                     }
1117                     else
1118                     {
1119                         for (int i = 0; i < isize; i++)
1120                         {
1121                             pDblTempo->set(i, in[2]->getAs<types::Sparse>()->get(i));
1122                         }
1123                     }
1124                     sci_grand_prm(iNumIter, pDblTempo, &pITOutTempo);
1125
1126                     if (pDblTempo->isComplex())
1127                     {
1128                         for (int i = 0; i < isize; i++)
1129                         {
1130                             cplxDbl.real(pITOutTempo->getAs<types::Double>()->get(i));
1131                             cplxDbl.imag(pITOutTempo->getAs<types::Double>()->getImg(i));
1132                             pITOutTempo->getAs<types::Sparse>()->set(i, cplxDbl);
1133                         }
1134                     }
1135                     else
1136                     {
1137                         for (int i = 0; i < isize; i++)
1138                         {
1139                             pITOut->getAs<types::Sparse>()->set(i, pITOutTempo->getAs<types::Double>()->get(i));
1140                         }
1141                     }
1142
1143                     delete pITOutTempo;
1144                     delete pDblTempo;
1145                     break;
1146                 }
1147                 default:
1148                 {
1149                     Scierror(999, _("%s: Wrong type for input argument: Matrix (full or sparse) or Hypermatrix of Reals, Complexes, Integers, Booleans, Strings or Polynomials expected.\n"), "grand");
1150                     return types::Function::Error;
1151                 }
1152             }
1153
1154             out.push_back(pITOut);
1155             break;
1156         }
1157         case 17: // uniform (def)
1158         {
1159             for (int i = 0; i < pDblOut->getSize(); i++)
1160             {
1161                 pDblOut->set(i, C2F(ranf)());
1162             }
1163
1164             out.push_back(pDblOut);
1165             break;
1166         }
1167         case 18: // uniform (unf)
1168         {
1169             for (int i = 0; i < 2; i++)
1170             {
1171                 if (vectpDblInput[i]->isScalar() == false)
1172                 {
1173                     delete pDblOut;
1174                     Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 4);
1175                     return types::Function::Error;
1176                 }
1177             }
1178
1179             double low  = vectpDblInput[0]->get(0);
1180             double high = vectpDblInput[1]->get(0);
1181
1182             if (low > high)
1183             {
1184                 delete pDblOut;
1185                 Scierror(999, _("%s: Wrong value for input arguments #%d and #%d: Low < High expected.\n"), "grand", 4, 5);
1186                 return types::Function::Error;
1187             }
1188
1189             for (int i = 0; i < pDblOut->getSize(); i++)
1190             {
1191                 pDblOut->set(i, low + (high - low) * C2F(ranf)());
1192             }
1193
1194             out.push_back(pDblOut);
1195             break;
1196         }
1197         case 19: // uniform (uin)
1198         {
1199             for (int i = 0; i < 2; i++)
1200             {
1201                 if (vectpDblInput[i]->isScalar() == false)
1202                 {
1203                     delete pDblOut;
1204                     Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 4);
1205                     return types::Function::Error;
1206                 }
1207             }
1208
1209             int low  = static_cast<int>(vectpDblInput[0]->get(0));
1210             int high = static_cast<int>(vectpDblInput[1]->get(0));
1211
1212             if (low > high)
1213             {
1214                 delete pDblOut;
1215                 Scierror(999, _("%s: Wrong value for input arguments #%d and #%d: Low < High expected.\n"), "grand", 4, 5);
1216                 return types::Function::Error;
1217             }
1218
1219             if ( low  != vectpDblInput[0]->get(0) ||
1220                     high != vectpDblInput[1]->get(0) ||
1221                     (high - low + 1) > 2147483561)
1222             {
1223                 delete pDblOut;
1224                 Scierror(999, _("%s: Wrong value for input arguments #%d and #%d: Low and High must be integers and (high - low + 1) <=  2147483561.\n"), "grand", 4, 5);
1225                 return types::Function::Error;
1226             }
1227
1228             for (int i = 0; i < pDblOut->getSize(); i++)
1229             {
1230                 pDblOut->set(i, C2F(ignuin)(vectpDblInput[0]->get(), vectpDblInput[1]->get()));
1231             }
1232
1233             out.push_back(pDblOut);
1234             break;
1235         }
1236         case 20: // uniform (lgi)
1237         {
1238             for (int i = 0; i < pDblOut->getSize(); i++)
1239             {
1240                 pDblOut->set(i, static_cast<double>(ignlgi()));
1241             }
1242
1243             out.push_back(pDblOut);
1244             break;
1245         }
1246         case 21: // getgen
1247         {
1248             delete pDblOut;
1249             types::String* pStrOut = new types::String(names_gen[current_base_gen]);
1250             out.push_back(pStrOut);
1251             break;
1252         }
1253         case 22: // setgen
1254         {
1255             delete pDblOut;
1256             wchar_t* wcsGen = pStrGenOrPhr->get(0);
1257
1258             if (wcscmp(wcsGen, L"mt") == 0)
1259             {
1260                 ConfigVariable::setCurrentBaseGen(MT);
1261             }
1262             else if (wcscmp(wcsGen, L"kiss") == 0)
1263             {
1264                 ConfigVariable::setCurrentBaseGen(KISS);
1265             }
1266             else if (wcscmp(wcsGen, L"clcg4") == 0)
1267             {
1268                 ConfigVariable::setCurrentBaseGen(CLCG4);
1269             }
1270             else if (wcscmp(wcsGen, L"clcg2") == 0)
1271             {
1272                 ConfigVariable::setCurrentBaseGen(CLCG2);
1273             }
1274             else if (wcscmp(wcsGen, L"urand") == 0)
1275             {
1276                 ConfigVariable::setCurrentBaseGen(URAND);
1277             }
1278             else if (wcscmp(wcsGen, L"fsultra") == 0)
1279             {
1280                 ConfigVariable::setCurrentBaseGen(FSULTRA);
1281             }
1282             else
1283             {
1284                 Scierror(999, _("%s: Wrong value for input argument #%d: '%s', '%s', '%s', '%s', '%s' or '%s' expected.\n"), "grand", 2, "mt", "kiss", "clcg4", "clcg2", "urand", "fsultra");
1285                 return types::Function::Error;
1286             }
1287
1288             int current_gen = ConfigVariable::getCurrentBaseGen();
1289             types::String* pStrOut = new types::String(names_gen[current_gen]);
1290             out.push_back(pStrOut);
1291             break;
1292         }
1293         case 23: // getsd
1294         {
1295             switch (current_base_gen)
1296             {
1297                 case MT:
1298                 {
1299                     pDblOut = new types::Double(625, 1);
1300                     get_state_mt(pDblOut->get());
1301                     break;
1302                 }
1303                 case KISS:
1304                 {
1305                     pDblOut = new types::Double(4, 1);
1306                     get_state_kiss(pDblOut->get());
1307                     break;
1308                 }
1309                 case CLCG4:
1310                 {
1311                     pDblOut = new types::Double(4, 1);
1312                     int current_clcg4 = ConfigVariable::getCurrentClcg4();
1313                     get_state_clcg4(current_clcg4, pDblOut->get());
1314                     break;
1315                 }
1316                 case CLCG2:
1317                 {
1318                     pDblOut = new types::Double(2, 1);
1319                     get_state_clcg2(pDblOut->get());
1320                     break;
1321                 }
1322                 case URAND:
1323                 {
1324                     pDblOut = new types::Double(1, 1);
1325                     get_state_urand(pDblOut->get());
1326                     break;
1327                 }
1328                 case FSULTRA:
1329                 {
1330                     pDblOut = new types::Double(40, 1);
1331                     get_state_fsultra(pDblOut->get());
1332                     break;
1333                 }
1334             }
1335
1336             out.push_back(pDblOut);
1337             break;
1338         }
1339         case 24: // setsd
1340         {
1341             delete pDblOut;
1342             int ierr = 0;
1343             switch (current_base_gen)
1344             {
1345                 case MT:
1346                 {
1347                     if (vectpDblInput[0]->isScalar())
1348                     {
1349                         ierr = set_state_mt_simple(vectpDblInput[0]->get(0));
1350                     }
1351                     else if (vectpDblInput[0]->getSize() == 625)
1352                     {
1353                         ierr = set_state_mt(vectpDblInput[0]->get());
1354                     }
1355                     else
1356                     {
1357                         Scierror(999, _("%s: Wrong size for input argument #%d : A scalar or a vector of size %d expected.\n"), "grand", 4, 625);
1358                         return types::Function::Error;
1359                     }
1360
1361                     break;
1362                 }
1363                 case KISS:
1364                 case CLCG4:
1365                 {
1366                     for (int i = 0; i < 4; i++)
1367                     {
1368                         if (vectpDblInput[i]->isScalar() == false)
1369                         {
1370                             Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 2);
1371                             return types::Function::Error;
1372                         }
1373                     }
1374
1375                     if (current_base_gen == KISS)
1376                     {
1377                         ierr = set_state_kiss(  vectpDblInput[0]->get(0),
1378                                                 vectpDblInput[1]->get(0),
1379                                                 vectpDblInput[2]->get(0),
1380                                                 vectpDblInput[3]->get(0));
1381                     }
1382                     else // CLCG4
1383                     {
1384                         ierr = set_seed_clcg4(  ConfigVariable::getCurrentClcg4(),
1385                                                 vectpDblInput[0]->get(0),
1386                                                 vectpDblInput[1]->get(0),
1387                                                 vectpDblInput[2]->get(0),
1388                                                 vectpDblInput[3]->get(0));
1389                     }
1390
1391                     break;
1392                 }
1393                 case CLCG2:
1394                 {
1395                     for (int i = 0; i < 2; i++)
1396                     {
1397                         if (vectpDblInput[i]->isScalar() == false)
1398                         {
1399                             Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 2);
1400                             return types::Function::Error;
1401                         }
1402                     }
1403
1404                     ierr = set_state_clcg2(vectpDblInput[0]->get(0), vectpDblInput[1]->get(0));
1405                     break;
1406                 }
1407                 case URAND:
1408                 {
1409                     if (vectpDblInput[0]->isScalar() == false)
1410                     {
1411                         Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", 2);
1412                         return types::Function::Error;
1413                     }
1414
1415                     ierr = set_state_urand(vectpDblInput[0]->get(0));
1416                     break;
1417                 }
1418                 case FSULTRA:
1419                 {
1420                     if (in.size() == 2)
1421                     {
1422                         if (vectpDblInput[0]->getRows() != 40 || vectpDblInput[0]->getCols() != 1)
1423                         {
1424                             Scierror(999, _("%s: Wrong size for input argument #%d : A vector of size %d x %d expected.\n"), "grand", 2, 40, 1);
1425                             return types::Function::Error;
1426                         }
1427
1428                         ierr = set_state_fsultra(vectpDblInput[0]->get());
1429                     }
1430                     else // in.size() == 3
1431                     {
1432                         for (int i = 0; i < 2; i++)
1433                         {
1434                             if (vectpDblInput[i]->isScalar() == false)
1435                             {
1436                                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 2);
1437                                 return types::Function::Error;
1438                             }
1439                         }
1440
1441                         ierr = set_state_fsultra_simple(vectpDblInput[0]->get(0), vectpDblInput[1]->get(0));
1442                     }
1443
1444                     break;
1445                 }
1446             }
1447
1448             if (ierr == 0)
1449             {
1450                 Scierror(999, _("%s: Wrong value for the last %d input argument(s).\n"), "grand", in.size() - 1);
1451                 return types::Function::Error;
1452             }
1453
1454             break;
1455         }
1456         case 25: // phr2sd
1457         {
1458             delete pDblOut;
1459             if (pStrGenOrPhr->isScalar() == false)
1460             {
1461                 Scierror(999, _("%s: Wrong type for input argument #%d : One string expected.\n"), "grand", 2);
1462                 return types::Function::Error;
1463             }
1464
1465             types::Double* pDblOut = new types::Double(1, 2);
1466             int size = (int)wcslen(pStrGenOrPhr->get(0));
1467             int piOut[2];
1468             char* strPhr = wide_string_to_UTF8(pStrGenOrPhr->get(0));
1469
1470             C2F(phrtsd)(strPhr, &size, piOut, piOut + 1, size);
1471
1472             pDblOut->set(0, static_cast<double>(piOut[0]));
1473             pDblOut->set(1, static_cast<double>(piOut[1]));
1474
1475             FREE(strPhr);
1476             out.push_back(pDblOut);
1477             break;
1478         }
1479         case 26: // setcgn
1480         {
1481             delete pDblOut;
1482             if (current_base_gen != CLCG4)
1483             {
1484                 sciprint(_("The %s option affects only the %s generator\n"), "setcgn", "clcg4");
1485             }
1486
1487             if (vectpDblInput[0]->isScalar() == false)
1488             {
1489                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", 2);
1490                 return types::Function::Error;
1491             }
1492
1493             if (vectpDblInput[0]->get(0) < 0 || vectpDblInput[0]->get(0) > Maxgen)
1494             {
1495                 Scierror(999, _("%s: Wrong value for input argument #%d : Must be between %d and %d.\n"), "grand", 0, Maxgen);
1496                 return types::Function::Error;
1497             }
1498
1499             ConfigVariable::setCurrentClcg4(static_cast<int>(vectpDblInput[0]->get(0)));
1500             double dOut = static_cast<double>(ConfigVariable::getCurrentClcg4());
1501             out.push_back(new types::Double(dOut));
1502             break;
1503         }
1504         case 27: // getcgn
1505         {
1506             delete pDblOut;
1507             double dOut = static_cast<double>(ConfigVariable::getCurrentClcg4());
1508             out.push_back(new types::Double(dOut));
1509             break;
1510         }
1511         case 28: // initgn
1512         {
1513             delete pDblOut;
1514             SeedType where;
1515             if (current_base_gen != CLCG4)
1516             {
1517                 sciprint(_("The %s option affects only the %s generator\n"), "initgn", "clcg4");
1518             }
1519
1520             if (vectpDblInput[0]->isScalar() == false)
1521             {
1522                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", 2);
1523                 return types::Function::Error;
1524             }
1525
1526             if ( vectpDblInput[0]->get(0) != 0 &&
1527                     vectpDblInput[0]->get(0) != -1 &&
1528                     vectpDblInput[0]->get(0) != 1)
1529             {
1530                 Scierror(999, _("%s: Wrong value for input argument #%d : Must be between %d, %d or %d.\n"), "grand", 2, -1, 0, 1);
1531                 return types::Function::Error;
1532             }
1533
1534             where = (SeedType)(int)(vectpDblInput[0]->get(0) + 1);
1535             init_generator_clcg4(ConfigVariable::getCurrentClcg4(), where);
1536             out.push_back(vectpDblInput[0]);
1537             break;
1538         }
1539         case 29: // setall
1540         {
1541             delete pDblOut;
1542             if (current_base_gen != CLCG4)
1543             {
1544                 sciprint(_("The %s option affects only the %s generator\n"), "setall", "clcg4");
1545             }
1546
1547             for (int i = 0; i < 4; i++)
1548             {
1549                 if (vectpDblInput[i]->isScalar() == false)
1550                 {
1551                     Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", i + 2);
1552                     return types::Function::Error;
1553                 }
1554             }
1555
1556             int ierr = set_initial_seed_clcg4(  vectpDblInput[0]->get(0),
1557                                                 vectpDblInput[1]->get(0),
1558                                                 vectpDblInput[2]->get(0),
1559                                                 vectpDblInput[3]->get(0));
1560             if (ierr == 0)
1561             {
1562                 Scierror(999, _("%s: Wrong value for the last %d input argument(s).\n"), "grand", 4);
1563                 return types::Function::Error;
1564             }
1565
1566             out.push_back(pStrMethod);
1567             break;
1568         }
1569         case 30: // advnst
1570         {
1571             delete pDblOut;
1572             if (current_base_gen != CLCG4)
1573             {
1574                 sciprint(_("The %s option affects only the %s generator\n"), "advnst", "clcg4");
1575             }
1576
1577             if (vectpDblInput[0]->isScalar() == false)
1578             {
1579                 Scierror(999, _("%s: Wrong type for input argument #%d : A scalar expected.\n"), "grand", 2);
1580                 return types::Function::Error;
1581             }
1582
1583             int k = static_cast<int>(vectpDblInput[0]->get(0));
1584
1585             if (k < 1)
1586             {
1587                 Scierror(999, _("%s: Wrong value for input argument #%d : Must be > %d.\n"), "grand", 2, 0);
1588                 return types::Function::Error;
1589             }
1590
1591             advance_state_clcg4(ConfigVariable::getCurrentClcg4(), k);
1592             out.push_back(new types::Double(static_cast<double>(k)));
1593             break;
1594         }
1595     }
1596
1597     return types::Function::OK;
1598 }
1599 /*--------------------------------------------------------------------------*/
1600
1601 template<class U>
1602 void sci_grand_prm(int iNumIter, U *pIn, types::InternalType** pOut)
1603 {
1604     U* pUTempo = NULL;
1605     types::InternalType* pITTempo = NULL;
1606     int* piDimsArray = NULL;
1607     int Dims = 0;
1608
1609     if ((pIn->getCols() == 1) && (pIn->getDims() == 2))
1610     {
1611         pOut[0]->getAs<U>()->resize(pIn->getRows(), iNumIter);
1612         pUTempo = pIn;
1613     }
1614     else if ((pIn->getRows() == 1) && (pIn->getDims() == 2))
1615     {
1616         pIn->transpose(pITTempo);
1617         pOut[0]->getAs<U>()->resize(iNumIter, pIn->getCols());
1618         pUTempo = pITTempo->getAs<U>();
1619     }
1620     else
1621     {
1622         piDimsArray = pOut[0]->getAs<U>()->getDimsArray();
1623         Dims = pOut[0]->getAs<U>()->getDims();
1624         piDimsArray[Dims] = iNumIter;
1625         pOut[0]->getAs<U>()->resize(piDimsArray, Dims + 1);
1626         pUTempo = pIn;
1627     }
1628
1629     int isize = pUTempo->getSize();
1630
1631     types::Double* pDblOut = new types::Double(isize, iNumIter, pUTempo->isComplex());
1632
1633     for (int i = 0; i < iNumIter; i++)
1634     {
1635         for (int j = 0; j < isize; j++)
1636         {
1637             pDblOut->set(isize * i + j, j);
1638         }
1639         C2F(genprm)(pDblOut->get() + (isize * i), &isize);
1640     }
1641
1642     if ((pIn->getCols() != 1) && (pIn->getRows() == 1) && (pIn->getDims() == 2))
1643     {
1644         pDblOut->transpose(pITTempo);
1645         delete pDblOut;
1646         pDblOut = pITTempo->getAs<types::Double>();
1647     }
1648
1649     if (pUTempo->isComplex() && pUTempo->isPoly() == false)
1650     {
1651         for (int i = 0; i < pOut[0]->getAs<U>()->getSize(); i++)
1652         {
1653             pOut[0]->getAs<U>()->set(i , pIn->get(static_cast<int>(pDblOut->get(i))));
1654             pOut[0]->getAs<U>()->setImg(i, pIn->getImg(static_cast<int>(pDblOut->get(i))));
1655         }
1656     }
1657     else
1658     {
1659         for (int i = 0; i < pOut[0]->getAs<U>()->getSize(); i++)
1660         {
1661             pOut[0]->getAs<U>()->set(i, pIn->get(static_cast<int>(pDblOut->get(i))));
1662         }
1663     }
1664
1665     if ((pIn->getCols() != 1) && (pIn->getRows() == 1) && (pIn->getDims() == 2))
1666     {
1667         delete pUTempo;
1668     }
1669
1670     delete pDblOut;
1671 }
1672
1673 /*--------------------------------------------------------------------------*/