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