Manages the complex case of NEV.
[scilab.git] / scilab / modules / arnoldi / sci_gateway / c / sci_eigs.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - Adeline CARNIS
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 <math.h>
14 #include <string.h>
15 #include "stack-c.h"
16 #include "isanan.h"
17 #include "core_math.h"
18 #include "gw_arnoldi.h"
19 #include "localization.h"
20 #include "Scierror.h"
21 #include "api_scilab.h"
22 #include "stdio.h"
23 #include "stdlib.h"
24 #include "sciprint.h"
25 #include "doublecomplex.h"
26 #include "MALLOC.h"
27 #include "eigs.h"
28
29 int sci_eigs(char *fname, unsigned long fname_len)
30 {
31     int *piAddressVarOne        = NULL;
32     int iRowsOne                        = 0;
33     int iColsOne                        = 0;
34     double elemt1                       = 0;
35     double elemt2                       = 0;
36     double* Areal                       = NULL;
37     doublecomplex* Acplx        = NULL;
38     int Asym                            = 1;
39     int Acomplex                        = 0;
40     int N                                       = 0;
41
42     int *piAddressVarTwo        = NULL;
43     int iTypeVarTwo                     = 0;
44     int iRowsTwo                        = 0;
45     int iColsTwo                        = 0;
46     double* Breal                       = NULL;
47     doublecomplex* Bcplx        = NULL;
48     int Bcomplex                        = 0;
49     int matB                            = 0;
50
51     int *piAddressVarThree      = NULL;
52     double dblNEV                       = 0;
53     int iNEV                            = 0;
54
55     int *piAddressVarFour       = NULL;
56     int iTypeVarFour            = 0;
57     int iRowsFour                       = 0;
58     int iColsFour                       = 0;
59     int iLen                            = 0;
60     char* pstData                       = NULL;
61     doublecomplex* SIGMA        = NULL;
62
63     int *piAddressVarFive       = NULL;
64     double dblMAXITER           = 0;
65
66     int *piAddressVarSix        = NULL;
67     double dblTOL                       = 0;
68
69     int *piAddressVarSeven      = NULL;
70     int TypeVarSeven            = 0;
71     int RowsSeven                       = 0;
72     int ColsSeven                       = 0;
73     double* dblNCV                      = NULL;
74
75     int *piAddressVarEight      = NULL;
76     int iTypeVarEight       = 0;
77     double dblCHOLB                     = 0;
78     int iCHOLB              = 0;
79
80     int *piAddressVarNine       = NULL;
81     int iTypeVarNine            = 0;
82     int iRowsNine                       = 0;
83     int iColsNine                       = 0;
84     double* RESID                       = NULL;
85     doublecomplex* RESIDC       = NULL;
86
87     int *piAddressVarTen        = NULL;
88     int iINFO                           = 0;
89
90     // Output arguments
91     doublecomplex* eigenvalue           = NULL;
92     doublecomplex* mat_eigenvalue       = NULL;
93     doublecomplex* eigenvector          = NULL;
94     int INFO_EUPD                                       = 0;
95     int error                                           = 0;
96
97     SciErr sciErr;
98     int iErr                            = 0;
99     int i                                       = 0;
100     int j                                       = 0;
101
102     CheckRhs(1, 10);
103     CheckLhs(0, 2);
104
105     /****************************************
106     *           First variable : A              *
107     *****************************************/
108
109     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne);
110     if (sciErr.iErr)
111     {
112         printError(&sciErr, 0);
113         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
114         return 0;
115     }
116
117     sciErr = getVarDimension(pvApiCtx, piAddressVarOne, &iRowsOne, &iColsOne);
118     //check if A is a square matrix
119     if (iRowsOne * iColsOne == 1 || iRowsOne != iColsOne)
120     {
121         Scierror(999, _("%s: Wrong type for input argument #%d: A square matrix expected.\n"), "eigs", 1);
122         return 0;
123     }
124
125     N = iRowsOne;
126
127     //check if A is complex
128     if (isVarComplex(pvApiCtx, piAddressVarOne))
129     {
130         sciErr = getComplexZMatrixOfDouble(pvApiCtx, piAddressVarOne, &iRowsOne, &iColsOne, &Acplx);
131         Acomplex = 1;
132     }
133     else
134     {
135         sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarOne, &iRowsOne, &iColsOne, &Areal);
136
137         for (i = 0; i < iColsOne; i++)
138         {
139             for (j = 0; j < i; j++)
140             {
141                 elemt1 = Areal[j + i * iColsOne];
142                 elemt2 = Areal[j * iColsOne + i];
143                 if (fabs(elemt1 - elemt2) > 0)
144                 {
145                     Asym = 0;
146                     break;
147                 }
148             }
149             if (Asym == 0)
150             {
151                 break;
152             }
153         }
154     }
155
156     /****************************************
157     *           Second variable : B             *
158     *****************************************/
159     sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddressVarTwo);
160     if (sciErr.iErr)
161     {
162         printError(&sciErr, 0);
163         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
164         return 0;
165     }
166
167     sciErr = getVarType(pvApiCtx, piAddressVarTwo, &iTypeVarTwo);
168     if (sciErr.iErr || iTypeVarTwo != sci_matrix)
169     {
170         printError(&sciErr, 0);
171         Scierror(999, _("%s: Wrong type for input argument #%d: An empty matrix or full or sparse square matrix expected.\n"), "eigs", 2);
172         return 0;
173     }
174
175     sciErr = getVarDimension(pvApiCtx, piAddressVarTwo, &iRowsTwo, &iColsTwo);
176     if (iRowsTwo * iColsTwo == 1 || iRowsTwo != iColsTwo)
177     {
178         Scierror(999, _("%s: Wrong dimension for input argument #%d: B must have the same size as A.\n"), "eigs", 2);
179         return 0;
180     }
181
182     matB = iRowsTwo * iColsTwo;
183     if (isVarComplex(pvApiCtx, piAddressVarTwo))
184     {
185         sciErr = getComplexZMatrixOfDouble(pvApiCtx, piAddressVarTwo, &iRowsTwo, &iColsTwo, &Bcplx);
186         Bcomplex = 1;
187     }
188     else
189     {
190         sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarTwo, &iRowsTwo, &iColsTwo, &Breal);
191     }
192
193     if (matB != 0)
194     {
195         if (Acomplex && !Bcomplex)
196         {
197             Bcplx = (doublecomplex*)malloc(N * N * sizeof(doublecomplex));
198             memset(Bcplx, 0, N * N * sizeof(doublecomplex));
199             Bcomplex = 1;
200             for (i = 0 ; i < N * N ;  i++)
201             {
202                 Bcplx[i].r = Breal[i];
203             }
204         }
205         if (!Acomplex && Bcomplex)
206         {
207             Acplx = (doublecomplex*)malloc(N * N * sizeof(doublecomplex));
208             memset(Acplx, 0, N * N * sizeof(doublecomplex));
209             Acomplex = 1;
210             for (i = 0 ; i < N * N ;  i++)
211             {
212                 Acplx[i].r = Areal[i];
213             }
214         }
215     }
216
217
218     /****************************************
219     *                           NEV                                     *
220     *****************************************/
221     sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddressVarThree);
222     if (sciErr.iErr)
223     {
224         printError(&sciErr, 0);
225         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
226         free(Acplx);
227         return 0;
228     }
229
230     iErr = getScalarDouble(pvApiCtx, piAddressVarThree, &dblNEV);
231     if (iErr)
232     {
233         Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 3);
234         return 0;
235     }
236
237     if (isVarComplex(pvApiCtx, piAddressVarThree))
238     {
239         Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 3);
240         return 0;
241     }
242
243     if (dblNEV != floor(dblNEV) || (dblNEV <= 0))
244     {
245         Scierror(999, _("%s: Wrong type for input argument #%d: k must be a positive integer.\n"), "eigs", 3);
246         return 0;
247     }
248
249     if (!finite(dblNEV))
250     {
251         Scierror(999, _("%s: Wrong value for input argument #%d: k must be in the range 1 to N.\n"), "eigs", 3);
252         return 0;
253     }
254
255
256     iNEV = (int)dblNEV;
257
258     /****************************************
259     *                   SIGMA AND WHICH                         *
260     *****************************************/
261     sciErr = getVarAddressFromPosition(pvApiCtx, 4, &piAddressVarFour);
262     if (sciErr.iErr)
263     {
264         printError(&sciErr, 0);
265         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 4);
266         return 0;
267     }
268
269     sciErr = getVarType(pvApiCtx, piAddressVarFour, &iTypeVarFour);
270     if (sciErr.iErr || (iTypeVarFour != sci_matrix && iTypeVarFour != sci_strings))
271     {
272         Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 4);
273         return 0;
274     }
275
276     if (iTypeVarFour == sci_strings)
277     {
278         int iErr = getAllocatedSingleString(pvApiCtx, piAddressVarFour, &pstData);
279         if (iErr)
280         {
281             return 0;
282         }
283
284         if (strcmp(pstData, "LM") != 0 && strcmp(pstData, "SM") != 0  && strcmp(pstData, "LR") != 0 && strcmp(pstData, "SR") != 0 && strcmp(pstData, "LI") != 0
285                 && strcmp(pstData, "SI") != 0 && strcmp(pstData, "LA") != 0 && strcmp(pstData, "SA") != 0 && strcmp(pstData, "BE") != 0)
286         {
287             if (!Acomplex && Asym)
288             {
289                 Scierror(999, _("%s: Wrong value for input argument #%d: Unrecognized sigma value.\n Sigma must be one of '%s', '%s', '%s', '%s' or '%s'.\n" ),
290                          "eigs", 4, "LM", "SM", "LA", "SA", "BE");
291                 return 0;
292             }
293             else
294             {
295                 Scierror(999, _("%s: Wrong value for input argument #%d: Unrecognized sigma value.\n Sigma must be one of '%s', '%s', '%s', '%s', '%s' or '%s'.\n " ),
296                          "eigs", 4, "LM", "SM", "LR", "SR", "LI", "SI");
297                 return 0;
298             }
299         }
300
301         if ((Acomplex || !Asym) && (strcmp(pstData, "LA") == 0 || strcmp(pstData, "SA") == 0 || strcmp(pstData, "BE") == 0))
302         {
303             Scierror(999, _("%s: Invalid sigma value for complex or non symmetric problem.\n"), "eigs", 4);
304             return 0;
305         }
306
307         if (!Acomplex && Asym && (strcmp(pstData, "LR") == 0 || strcmp(pstData, "SR") == 0 || strcmp(pstData, "LI") == 0 || strcmp(pstData, "SI") == 0))
308         {
309             Scierror(999, _("%s: Invalid sigma value for real symmetric problem.\n"), "eigs", 4);
310             return 0;
311         }
312
313         SIGMA = (doublecomplex*)malloc(1 * sizeof(doublecomplex));
314         SIGMA[0].r = 0;
315         SIGMA[0].i = 0;
316     }
317
318     if (iTypeVarFour == sci_matrix)
319     {
320         sciErr = getVarDimension(pvApiCtx, piAddressVarFour, &iRowsFour, &iColsFour);
321         if (iRowsFour * iColsFour != 1)
322         {
323             Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 4);
324             return 0;
325         }
326
327         SIGMA = (doublecomplex*)MALLOC(1 * sizeof(doublecomplex));
328         if (getScalarComplexDouble(pvApiCtx, piAddressVarFour, &SIGMA[0].r, &SIGMA[0].i))
329         {
330             printError(&sciErr, 0);
331             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 4);
332             return 0;
333         }
334
335         if (C2F(isanan)(&SIGMA[0].r) || C2F(isanan)(&SIGMA[0].i))
336         {
337             Scierror(999, _("%s: Wrong type for input argument #%d: sigma must be a real.\n"), "eigs", 4);
338             return 0;
339         }
340
341         pstData = "LM";
342     }
343
344     /****************************************
345     *                           MAXITER                                 *
346     *****************************************/
347     sciErr = getVarAddressFromPosition(pvApiCtx, 5, &piAddressVarFive);
348     if (sciErr.iErr)
349     {
350         printError(&sciErr, 0);
351         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 5);
352         free(SIGMA);
353         return 0;
354     }
355
356     iErr = getScalarDouble(pvApiCtx, piAddressVarFive, &dblMAXITER);
357     if (iErr)
358     {
359         Scierror(999, _("%s: Wrong type for input argument #%d: %s must be a scalar.\n"), "eigs", 5, "opts.maxiter");
360         return 0;
361     }
362
363     if ((dblMAXITER != floor(dblMAXITER)) || (dblMAXITER <= 0))
364     {
365         Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer positive value.\n"), "eigs", 5, "opts.maxiter");
366         return 0;
367     }
368
369     /****************************************
370     *                                   TOL                             *
371     *****************************************/
372     sciErr = getVarAddressFromPosition(pvApiCtx, 6, &piAddressVarSix);
373     if (sciErr.iErr)
374     {
375         printError(&sciErr, 0);
376         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 6);
377         return 0;
378     }
379
380     iErr = getScalarDouble(pvApiCtx, piAddressVarSix, &dblTOL);
381     if (iErr)
382     {
383         Scierror(999, _("%s: Wrong type for input argument #%d: %s must be a real scalar.\n"), "eigs", 6, "opts.tol");
384         return 0;
385     }
386
387     if (C2F(isanan)(&dblTOL))
388     {
389         Scierror(999, _("%s: Wrong type for input argument #%d: %s must be a real scalar.\n"), "eigs", 6, "opts.tol");
390         return 0;
391     }
392
393     /****************************************
394     *                                   NCV                             *
395     *****************************************/
396     sciErr = getVarAddressFromPosition(pvApiCtx, 7, &piAddressVarSeven);
397     if (sciErr.iErr)
398     {
399         printError(&sciErr, 0);
400         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 7);
401         return 0;
402     }
403
404     sciErr = getVarType(pvApiCtx, piAddressVarSeven, &TypeVarSeven);
405     if (sciErr.iErr || TypeVarSeven != sci_matrix)
406     {
407         printError(&sciErr, 0);
408         Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 7, "opts.ncv");
409         return 0;
410     }
411     else
412     {
413         if (isVarComplex(pvApiCtx, piAddressVarSeven))
414         {
415             Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 7, "opts.ncv");
416             0;
417         }
418         else
419         {
420             sciErr = getVarDimension(pvApiCtx, piAddressVarSeven, &RowsSeven, &ColsSeven);
421             if (RowsSeven * ColsSeven > 1)
422             {
423                 Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 7, "opts.ncv");
424                 return 0;
425             }
426
427             if (RowsSeven * ColsSeven == 1)
428             {
429                 sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarSeven, &RowsSeven, &ColsSeven, &dblNCV);
430                 if (sciErr.iErr)
431                 {
432                     printError(&sciErr, 0);
433                     Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 7);
434                     return 0;
435                 }
436
437                 if (dblNCV[0] != floor(dblNCV[0]))
438                 {
439                     Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 7, "opts.ncv");
440                     return 0;
441                 }
442             }
443         }
444     }
445
446     /****************************************
447     *                           CHOLB                           *
448     *****************************************/
449     sciErr = getVarAddressFromPosition(pvApiCtx, 8, &piAddressVarEight);
450     if (sciErr.iErr)
451     {
452         printError(&sciErr, 0);
453         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 8);
454         return 0;
455     }
456
457     sciErr = getVarType(pvApiCtx, piAddressVarEight, &iTypeVarEight);
458     if (sciErr.iErr || iTypeVarEight != sci_matrix && iTypeVarEight != sci_boolean)
459     {
460         Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar or a boolean.\n"), "eigs", 8, "opts.cholB");
461         return 0;
462     }
463
464     if (iTypeVarEight == sci_boolean)
465     {
466         iErr = getScalarBoolean(pvApiCtx, piAddressVarEight, &iCHOLB);
467         if (iErr)
468         {
469             Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar or a boolean.\n"), "eigs", 8, "opts.cholB");
470             return 0;
471         }
472
473         if (iCHOLB != 1 && iCHOLB != 0)
474         {
475             Scierror(999, _("%s: Wrong value for input argument #%d: %s must be %s or %s.\n"), "eigs", 8, "opts.cholB", "%f", "%t");
476             return 0;
477         }
478         dblCHOLB = (double) iCHOLB;
479     }
480
481     if (iTypeVarEight == sci_matrix)
482     {
483         iErr = getScalarDouble(pvApiCtx, piAddressVarEight, &dblCHOLB);
484         if (iErr)
485         {
486             Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar or a boolean.\n"), "eigs", 8, "opts.cholB");
487             return 0;
488         }
489
490         if (dblCHOLB != 1 && dblCHOLB != 0)
491         {
492             Scierror(999, _("%s: Wrong value for input argument #%d: %s must be %s or %s.\n"), "eigs", 8, "opts.cholB", "%f", "%t");
493             return 0;
494         }
495     }
496
497     /****************************************
498     *                           RESID                           *
499     *****************************************/
500     sciErr = getVarAddressFromPosition(pvApiCtx, 9, &piAddressVarNine);
501     if (sciErr.iErr)
502     {
503         printError(&sciErr, 0);
504         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 9);
505         return 0;
506     }
507
508     sciErr = getVarType(pvApiCtx, piAddressVarNine, &iTypeVarNine);
509     if (sciErr.iErr || iTypeVarNine != sci_matrix)
510     {
511         printError(&sciErr, 0);
512         Scierror(999, _("%s: Wrong type for input argument #%d: A real or complex matrix expected.\n"), "eigs", 9);
513         return 0;
514     }
515     else
516     {
517         sciErr = getVarDimension(pvApiCtx, piAddressVarNine, &iRowsNine, &iColsNine);
518         if (iRowsNine * iColsNine == 1 || iRowsNine * iColsNine != N)
519         {
520             Scierror(999, _("%s: Wrong dimension for input argument #%d: Start vector %s must be N by 1.\n"), "eigs", 9, "opts.resid");
521             return 0;
522         }
523     }
524
525     if (!Acomplex && !Bcomplex)
526     {
527         if (isVarComplex(pvApiCtx, piAddressVarNine))
528         {
529             Scierror(999, _("%s: Wrong type for input argument #%d: Start vector %s must be real for real problems.\n"), "eigs", 9, "opts.resid");
530             return 0;
531         }
532         else
533         {
534             sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarNine, &iRowsNine, &iColsNine, &RESID);
535             if (sciErr.iErr)
536             {
537                 printError(&sciErr, 0);
538                 Scierror(999, _("%s: Can not read input argument #%d.\n"), "eigs", 9);
539                 return 0;
540             }
541         }
542     }
543     else
544     {
545         sciErr = getComplexZMatrixOfDouble(pvApiCtx, piAddressVarNine, &iRowsNine, &iColsNine, &RESIDC);
546         if (sciErr.iErr)
547         {
548             printError(&sciErr, 0);
549             Scierror(999, _("%s: Can not read input argument #%d.\n"), "eigs", 9);
550             return 0;
551         }
552     }
553
554     /****************************************
555     *                           INFO                            *
556     *****************************************/
557     sciErr = getVarAddressFromPosition(pvApiCtx, 10, &piAddressVarTen);
558     if (sciErr.iErr)
559     {
560         printError(&sciErr, 0);
561         Scierror(999, _("%s: Can not read input argument #%d.\n"), "eigs", 9);
562         return 0;
563     }
564
565     iErr = getScalarInteger32(pvApiCtx, piAddressVarTen, &iINFO);
566     if (iErr)
567     {
568         Scierror(999, _("%s: Wrong type for input argument #%d: An integer expected.\n"), "eigs", 1);
569         return 0;
570     }
571
572     // Initialization output arguments
573     eigenvalue = (doublecomplex*) malloc((iNEV + 1) * sizeof(doublecomplex));
574     memset(eigenvalue, 0, (iNEV + 1) * sizeof(doublecomplex));
575
576     if (Lhs > 1)
577     {
578         mat_eigenvalue = (doublecomplex*) malloc((iNEV + 1) * (iNEV + 1) * sizeof(doublecomplex));
579         memset(mat_eigenvalue, 0, (iNEV + 1) * (iNEV + 1) * sizeof(doublecomplex));
580
581         eigenvector = (doublecomplex*) malloc(N * (iNEV + 1) * sizeof(doublecomplex));
582         memset(eigenvector, 0, N * (iNEV + 1) * sizeof(doublecomplex));
583     }
584
585     error = eigs(Areal, Acplx, N, Acomplex, Asym, Breal, Bcplx, Bcomplex, matB, iNEV, SIGMA, pstData, &dblMAXITER,
586                  &dblTOL, dblNCV, RESID, RESIDC, &iINFO, &dblCHOLB, INFO_EUPD, eigenvalue, eigenvector);
587
588     switch (error)
589     {
590         case -1 :
591             if (Asym && !Acomplex && !Bcomplex)
592             {
593                 Scierror(999, _("%s: Wrong value for input argument #%d: For real symmetric problems, NCV must be k < NCV <= N.\n"), "eigs", 7);
594             }
595             else
596             {
597                 if (!Asym && !Acomplex && !Bcomplex)
598                 {
599                     Scierror(999, _("%s: Wrong value for input argument #%d: For real non symmetric problems, NCV must be k + 2 < NCV <= N.\n"), "eigs", 7);
600                 }
601                 else
602                 {
603                     Scierror(999, _("%s: Wrong value for input argument #%d: For complex problems, NCV must be k + 1 < NCV <= N.\n"), "eigs", 7);
604                 }
605             }
606             PutLhsVar();
607             return 0;
608
609         case -2 :
610             if (Asym && !Acomplex && !Bcomplex)
611             {
612                 Scierror(999, _("%s: Wrong value for input argument #%d: For real symmetric problems, k must be an integer in the range 1 to N - 1.\n"), "eigs", 3);
613             }
614             else
615             {
616                 Scierror(999, _("%s: Wrong value for input argument #%d: For real non symmetric or complex problems, k must be an integer in the range 1 to N - 2.\n"), "eigs", 3);
617             }
618             PutLhsVar();
619             return 0;
620
621         case -3 :
622             Scierror(999, _("%s: Wrong type for input argument #%d: B must be symmetric or hermitian, definite, semi positive.\n"), "eigs", 2);
623             PutLhsVar();
624             return 0;
625
626         case -4 :
627             if (!Acomplex && !Bcomplex)
628             {
629                 if (Asym)
630                 {
631                     Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "DSAUPD", iINFO);
632                 }
633                 else
634                 {
635                     Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "DNAUPD", iINFO);
636                 }
637             }
638             else
639             {
640                 Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "ZNAUPD", iINFO);
641             }
642             PutLhsVar();
643             return 0;
644
645         case -5 :
646             if (!Acomplex && !Bcomplex)
647             {
648                 if (Asym)
649                 {
650                     Scierror(999, _("%s: Error with %s: unknown mode returned.\n"), "eigs", "DSAUPD");
651                 }
652                 else
653                 {
654                     Scierror(999, _("%s: Error with %s: unknown mode returned.\n"), "eigs", "DNAUPD");
655                 }
656             }
657             else
658             {
659                 Scierror(999, _("%s: Error with %s: unknown mode returned.\n"), "eigs", "ZNAUPD");
660             }
661             PutLhsVar();
662             return 0;
663
664         case -6 :
665             if (!Acomplex && !Bcomplex)
666             {
667                 if (Asym)
668                 {
669                     Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "DSEUPD", INFO_EUPD);
670                 }
671                 else
672                 {
673                     Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "DNEUPD", INFO_EUPD);
674                 }
675             }
676             else
677             {
678                 Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "ZNEUPD", INFO_EUPD);
679             }
680             PutLhsVar();
681             free(mat_eigenvalue);
682             return 0;
683     }
684
685     if (Lhs <= 1)
686     {
687         sciErr = createComplexZMatrixOfDouble(pvApiCtx, Rhs + 1, iNEV, 1, eigenvalue);
688         if (sciErr.iErr)
689         {
690             printError(&sciErr, 0);
691             Scierror(999, _("%s: Memory allocation error.\n"), fname);
692             return 0;
693         }
694
695         LhsVar(1) = Rhs + 1;
696     }
697     else
698     {
699         // create a matrix which contains the eigenvalues
700         for (i = 0; i < iNEV ; i++)
701         {
702             mat_eigenvalue[i * iNEV + i].r = eigenvalue[i].r;
703             mat_eigenvalue[i * iNEV + i].i = eigenvalue[i].i;
704         }
705
706         sciErr = createComplexZMatrixOfDouble(pvApiCtx, Rhs + 1, iNEV, iNEV, mat_eigenvalue);
707         if (sciErr.iErr)
708         {
709             printError(&sciErr, 0);
710             Scierror(999, _("%s: Memory allocation error.\n"), fname);
711             return 0;
712         }
713
714         sciErr = createComplexZMatrixOfDouble(pvApiCtx, Rhs + 2, N, iNEV, eigenvector);
715         if (sciErr.iErr)
716         {
717             printError(&sciErr, 0);
718             Scierror(999, _("%s: Memory allocation error.\n"), fname);
719             return 0;
720         }
721
722         LhsVar(1) = Rhs + 1;
723         LhsVar(2) = Rhs + 2;
724     }
725
726     if (iTypeVarFour == sci_strings)
727     {
728         freeAllocatedSingleString(pstData);
729     }
730
731     free(SIGMA);
732
733     free(eigenvalue);
734
735     if (matB != 0)
736     {
737         if (Acomplex && !Bcomplex)
738         {
739             free(Bcplx);
740         }
741         if (!Acomplex && Bcomplex)
742         {
743             free(Acplx);
744         }
745     }
746
747     if (Lhs > 1)
748     {
749         free(mat_eigenvalue);
750         free(eigenvector);
751     }
752     PutLhsVar();
753     return 0;
754 }
755