Fix localization issues
[scilab.git] / scilab / modules / linear_algebra / sci_gateway / c / sci_norm.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2013 - Scilab Enterprises - Paul Bignier
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.1-en.txt
10  *
11  */
12 #include <stdio.h>
13 #include "api_scilab.h"
14 #include "gw_linear_algebra2.h"
15 #include "Scierror.h"
16 #include "localization.h"
17 #include "MALLOC.h"
18 #include "norm.h"
19
20 /*--------------------------------------------------------------------------*/
21 int C2F(intnorm)(char *fname, unsigned long fname_len)
22 {
23     SciErr sciErr;
24     // Arguments' addresses
25     int *pAAddr         = NULL;
26     int *pflagAddr      = NULL;
27     // Arguments' values
28     double *pA          = NULL;
29     char *pflagChar     = NULL;
30     doublecomplex *pAC  = NULL;
31     double flagVal = 0;
32     // Arguments' properties (type, dimensions, length)
33     int iLen = 0;
34     int iType = 0;
35     int iRows = 0;
36     int iCols = 0;
37     // Return value
38     double ret = 0;
39
40     double RowsColsTemp = 0;
41     int i = 0;
42     int isMat = 0;
43     int isComplex = 0;
44
45     CheckInputArgument(pvApiCtx, 1, 2);
46     CheckOutputArgument(pvApiCtx, 1, 1);
47
48     // Checking A.
49     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &pAAddr); // Retrieving A address.
50     if (sciErr.iErr)
51     {
52         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
53         printError(&sciErr, 0);
54         return 0;
55     }
56
57     sciErr = getVarType(pvApiCtx, pAAddr, &iType); // Retrieving A type.
58     if (iType != sci_matrix)
59     {
60         OverLoad(1);
61         return 0;
62     }
63
64     if (isVarComplex(pvApiCtx, pAAddr))
65     {
66         sciErr = getComplexZMatrixOfDouble(pvApiCtx, pAAddr, &iRows, &iCols, &pAC);
67         if (sciErr.iErr)
68         {
69             printError(&sciErr, 0);
70             Scierror(202, _("%s: Wrong type for argument #%d: Real or complex matrix expected.\n"), fname, 1);
71             return 0;
72         }
73
74         isComplex = 1;
75         for (i = 0; i < iRows * iCols; ++i) // Checking A for %inf, which is not supported by Lapack.
76         {
77             if (isinf(pAC[i].r) != 0 || isinf(pAC[i].i) != 0 || ISNAN(pAC[i].r) || ISNAN(pAC[i].i))
78             {
79                 Scierror(264, _("%s: Wrong value for argument #%d: Must not contain NaN or Inf.\n"), fname, 1);
80                 return 0;
81             }
82         }
83     }
84     else
85     {
86         sciErr = getMatrixOfDouble(pvApiCtx, pAAddr, &iRows, &iCols, &pA);
87         if (sciErr.iErr)
88         {
89             printError(&sciErr, 0);
90             Scierror(202, _("%s: Wrong type for argument #%d: Real or complex matrix expected.\n"), fname, 1);
91             return 0;
92         }
93
94         for (i = 0 ; i < iRows * iCols ; i++) // Checking A for %inf, which is not supported by Lapack.
95         {
96             if (isinf(pA[i]) != 0 || ISNAN(pA[i]))
97             {
98                 Scierror(264, _("%s: Wrong value for argument #%d: Must not contain NaN or Inf.\n"), fname, 1);
99                 return 0;
100             }
101         }
102     }
103     if (iRows == 0) // A = [] => returning 0.
104     {
105         createScalarDouble(pvApiCtx, Rhs + 1, 0);
106         AssignOutputVariable(pvApiCtx, 1) = Rhs + 1;
107         return 0;
108     }
109
110     if (iRows > 1 && iCols > 1) // If A is a matrix, only 1, 2 and %inf are allowed as second argument.
111     {
112         isMat = 1;
113     }
114
115     if (iRows == 1) // If iRows == 1, then transpose A to consider it like a vector.
116     {
117         RowsColsTemp = iRows;
118         iRows = iCols;
119         iCols = (int)RowsColsTemp;
120     }
121
122     if (Rhs == 1) // One argument => returning norm 2.
123     {
124         // Call normP() or normPC().
125         if (isComplex)
126         {
127             ret = normPC(pAC, iRows, iCols, 2); // if A is a complex matrix, call the complex function.
128         }
129         else
130         {
131             ret = normP(pA, iRows, iCols, 2);
132         }
133
134         createScalarDouble(pvApiCtx, Rhs + 1, ret);
135         AssignOutputVariable(pvApiCtx, 1) = Rhs + 1;
136         return 0;
137     }
138
139     // Checking flag.
140     sciErr = getVarAddressFromPosition(pvApiCtx, 2, &pflagAddr); // Retrieving flag address.
141     if (sciErr.iErr)
142     {
143         printError(&sciErr, 0);
144         return 0;
145     }
146
147     sciErr = getVarType(pvApiCtx, pflagAddr, &iType); // Retrieving flag type.
148     if (iType != sci_strings && iType != sci_matrix)
149     {
150         Scierror(999, _("%s: Wrong type for input argument #%d: String or integer expected.\n"), fname, 2);
151         return 0;
152     }
153
154     if (iType == sci_strings)
155     {
156         if (getAllocatedSingleString(pvApiCtx, pflagAddr, &pflagChar)) // Retrieving flag dimensions.
157         {
158             Scierror(205, _("%s: Wrong size for input argument #%d: A string expected.\n"), fname, 2);
159             return 0;
160         }
161
162         iLen = (int)strlen(pflagChar);
163         if (iLen != 3 && iLen != 1)
164         {
165             Scierror(116, _("%s: Wrong value for input argument #%d: %s, %s, %s, or %s expected.\n"), fname, 2, "i", "inf", "f", "fro");
166             freeAllocatedSingleString(pflagChar);
167             return 0;
168         }
169
170         if (strcmp(pflagChar, "inf") != 0 && strcmp(pflagChar, "i") != 0 &&
171                 strcmp(pflagChar, "fro") != 0 && strcmp(pflagChar, "f") != 0) // flag must be = "inf", "i", "fro" or "f".
172         {
173             Scierror(116, _("%s: Wrong value for input argument #%d: %s, %s, %s or %s expected.\n"), fname, 2, "i", "inf", "f", "fro");
174             freeAllocatedSingleString(pflagChar);
175             return 0;
176         }
177
178         if (isComplex)
179         {
180             ret = normStringC(pAC, iRows, iCols, pflagChar); // if A is a complex matrix, call the complex function.
181         }
182         else
183         {
184             ret = normString(pA, iRows, iCols, pflagChar); // flag is a string => returning the corresponding norm.
185         }
186
187         createScalarDouble(pvApiCtx, Rhs + 1, ret);
188         AssignOutputVariable(pvApiCtx, 1) = Rhs + 1;
189         freeAllocatedSingleString(pflagChar);
190         return 0;
191     }
192     else
193     {
194         if (isVarComplex(pvApiCtx, pflagAddr))
195         {
196             Scierror(999, _("%s: Wrong type for input argument #%d: A real expected.\n"), fname, 2);
197             return 0;
198         }
199         if (getScalarDouble(pvApiCtx, pflagAddr, &flagVal)) // Retrieving flag value & dimensions as a double.
200         {
201             printError(&sciErr, 0);
202             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, 2);
203             return 0;
204         }
205
206         // Call the norm functions.
207         if (isinf(flagVal) == 1 && flagVal > 0) // flag = %inf
208         {
209             if (isComplex)
210             {
211                 ret = normStringC(pAC, iRows, iCols, "inf"); // if A is a complex matrix, call the complex function.
212             }
213             else
214             {
215                 ret = normString(pA, iRows, iCols, "inf"); // The infinite norm is computed by normString().
216             }
217
218             createScalarDouble(pvApiCtx, Rhs + 1, ret);
219             AssignOutputVariable(pvApiCtx, 1) = Rhs + 1;
220             return 0;
221         }
222         else
223         {
224             if (isMat == 1 && flagVal != 1 && flagVal != 2 && isinf(flagVal) == 0)
225             {
226                 Scierror(116, _("%s: Wrong value for input argument #%d: %s, %s, %s or %s expected.\n"), fname, 2, "1", "2", "inf", "-inf");
227                 return 0;
228             }
229
230             if (isComplex)
231             {
232                 ret = normPC(pAC, iRows, iCols, flagVal); // if A is a complex matrix, call the complex function.
233             }
234             else
235             {
236                 ret = normP(pA, iRows, iCols, flagVal); // flag is an integer => returning the corresponding norm.
237             }
238
239             createScalarDouble(pvApiCtx, Rhs + 1, ret);
240             AssignOutputVariable(pvApiCtx, 1) = Rhs + 1;
241             return 0;
242         }
243     }
244
245     return 0;
246 }
247 /*--------------------------------------------------------------------------*/