1 /*
2 * fn-complex.c: Built in complex number functions and functions registration
3 *
4 * Authors:
5 * Michael Meeks <michael@ximian.com>
6 * Jukka-Pekka Iivonen (iivonen@iki.fi)
7 * Morten Welinder (terra@gnome.org)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23 #include <gnumeric-config.h>
24 #include <gnumeric.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <func.h>
28
29 #include <complex.h>
30 #include <sf-gamma.h>
31 #include <parse-util.h>
32 #include <cell.h>
33 #include <expr.h>
34 #include <value.h>
35 #include <mathfunc.h>
36 #include <gnm-i18n.h>
37
38 #include <goffice/goffice.h>
39 #include <gnm-plugin.h>
40 #include "gsl-complex.h"
41
42
43 GNM_PLUGIN_MODULE_HEADER;
44
45 /* Converts a complex number string into its coefficients. Returns 0 if ok,
46 * 1 if an error occurred.
47 */
48 static int
value_get_as_complex(GnmValue const * val,gnm_complex * res,char * imunit)49 value_get_as_complex (GnmValue const *val, gnm_complex *res, char *imunit)
50 {
51 if (VALUE_IS_NUMBER (val)) {
52 *res = GNM_CREAL (value_get_as_float (val));
53 *imunit = 'i';
54 return 0;
55 } else {
56 return gnm_complex_from_string (res,
57 value_peek_string (val),
58 imunit);
59 }
60 }
61
62 static GnmValue *
value_new_complex(gnm_complex const * c,char imunit)63 value_new_complex (gnm_complex const *c, char imunit)
64 {
65 if (gnm_complex_invalid_p (c))
66 return value_new_error_NUM (NULL);
67 else if (GNM_CREALP (*c))
68 return value_new_float (c->re);
69 else
70 return value_new_string_nocopy (gnm_complex_to_string (c, imunit));
71 }
72
73 static GnmValue *
value_new_complexv(gnm_complex c,char imunit)74 value_new_complexv (gnm_complex c, char imunit)
75 {
76 return value_new_complex (&c, imunit);
77 }
78
79
80 /***************************************************************************/
81
82 static GnmFuncHelp const help_complex[] = {
83 { GNM_FUNC_HELP_NAME, F_("COMPLEX:a complex number of the form @{x} + @{y}@{i}") },
84 { GNM_FUNC_HELP_ARG, F_("x:real part") },
85 { GNM_FUNC_HELP_ARG, F_("y:imaginary part") },
86 { GNM_FUNC_HELP_ARG, F_("i:the suffix for the complex number, either \"i\" or \"j\"; defaults to \"i\"") },
87 { GNM_FUNC_HELP_NOTE, F_("If @{i} is neither \"i\" nor \"j\", COMPLEX returns #VALUE!") },
88 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
89 { GNM_FUNC_HELP_EXAMPLES, "=COMPLEX(1,-1)" },
90 { GNM_FUNC_HELP_END}
91 };
92
93 static GnmValue *
gnumeric_complex(GnmFuncEvalInfo * ei,GnmValue const * const * argv)94 gnumeric_complex (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
95 {
96 gnm_complex c = GNM_CMAKE (value_get_as_float (argv[0]),
97 value_get_as_float (argv[1]));
98 char const *suffix = argv[2] ? value_peek_string (argv[2]) : "i";
99
100 if (strcmp (suffix, "i") != 0 && strcmp (suffix, "j") != 0)
101 return value_new_error_VALUE (ei->pos);
102
103 return value_new_complex (&c, *suffix);
104 }
105
106 /***************************************************************************/
107
108 static GnmFuncHelp const help_imaginary[] = {
109 { GNM_FUNC_HELP_NAME, F_("IMAGINARY:the imaginary part of the complex number @{z}") },
110 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
111 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
112 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
113 { GNM_FUNC_HELP_EXAMPLES, "=IMAGINARY(\"132-j\")" },
114 { GNM_FUNC_HELP_SEEALSO, "IMREAL" },
115 { GNM_FUNC_HELP_END}
116 };
117
118 static GnmValue *
gnumeric_imaginary(GnmFuncEvalInfo * ei,GnmValue const * const * argv)119 gnumeric_imaginary (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
120 {
121 gnm_complex c;
122 char imunit;
123
124 if (VALUE_IS_NUMBER (argv[0]))
125 return value_new_float (0.0);
126
127 if (value_get_as_complex (argv[0], &c, &imunit))
128 return value_new_error_NUM (ei->pos);
129
130 return value_new_float (c.im);
131 }
132
133 /***************************************************************************/
134
135 static GnmFuncHelp const help_imabs[] = {
136 { GNM_FUNC_HELP_NAME, F_("IMABS:the absolute value of the complex number @{z}") },
137 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
138 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
139 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
140 { GNM_FUNC_HELP_EXAMPLES, "=IMABS(\"2-j\")" },
141 { GNM_FUNC_HELP_SEEALSO, "IMAGINARY,IMREAL" },
142 { GNM_FUNC_HELP_END}
143 };
144
145 static GnmValue *
gnumeric_imabs(GnmFuncEvalInfo * ei,GnmValue const * const * argv)146 gnumeric_imabs (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
147 {
148 gnm_complex c;
149 char imunit;
150
151 if (value_get_as_complex (argv[0], &c, &imunit))
152 return value_new_error_NUM (ei->pos);
153
154 return value_new_float (GNM_CABS (c));
155 }
156
157 /***************************************************************************/
158
159 static GnmFuncHelp const help_imreal[] = {
160 { GNM_FUNC_HELP_NAME, F_("IMREAL:the real part of the complex number @{z}") },
161 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
162 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
163 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
164 { GNM_FUNC_HELP_EXAMPLES, "=IMREAL(\"132-j\")" },
165 { GNM_FUNC_HELP_SEEALSO, "IMAGINARY" },
166 { GNM_FUNC_HELP_END}
167 };
168
169 static GnmValue *
gnumeric_imreal(GnmFuncEvalInfo * ei,GnmValue const * const * argv)170 gnumeric_imreal (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
171 {
172 gnm_complex c;
173 char imunit;
174
175 if (VALUE_IS_NUMBER (argv[0]))
176 return value_dup (argv[0]);
177
178 if (value_get_as_complex (argv[0], &c, &imunit))
179 return value_new_error_NUM (ei->pos);
180
181 return value_new_float (c.re);
182 }
183
184 /***************************************************************************/
185
186 static GnmFuncHelp const help_imconjugate[] = {
187 { GNM_FUNC_HELP_NAME, F_("IMCONJUGATE:the complex conjugate of the complex number @{z}") },
188 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
189 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
190 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
191 { GNM_FUNC_HELP_EXAMPLES, "=IMCONJUGATE(\"1-j\")" },
192 { GNM_FUNC_HELP_SEEALSO, "IMAGINARY,IMREAL" },
193 { GNM_FUNC_HELP_END}
194 };
195
196 static GnmValue *
gnumeric_imconjugate(GnmFuncEvalInfo * ei,GnmValue const * const * argv)197 gnumeric_imconjugate (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
198 {
199 gnm_complex c;
200 char imunit;
201
202 if (value_get_as_complex (argv[0], &c, &imunit))
203 return value_new_error_NUM (ei->pos);
204
205 return value_new_complexv (GNM_CCONJ (c), imunit);
206 }
207
208 /***************************************************************************/
209
210 static GnmFuncHelp const help_iminv[] = {
211 { GNM_FUNC_HELP_NAME, F_("IMINV:the reciprocal, or inverse, of the complex number @{z}") },
212 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
213 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
214 { GNM_FUNC_HELP_EXAMPLES, "=IMINV(\"1-j\")" },
215 { GNM_FUNC_HELP_END}
216 };
217
218 static GnmValue *
gnumeric_iminv(GnmFuncEvalInfo * ei,GnmValue const * const * argv)219 gnumeric_iminv (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
220 {
221 gnm_complex c;
222 char imunit;
223
224 if (value_get_as_complex (argv[0], &c, &imunit))
225 return value_new_error_NUM (ei->pos);
226
227 return value_new_complexv (GNM_CINV (c), imunit);
228 }
229
230 /***************************************************************************/
231
232 static GnmFuncHelp const help_imneg[] = {
233 { GNM_FUNC_HELP_NAME, F_("IMNEG:the negative of the complex number @{z}") },
234 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
235 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
236 { GNM_FUNC_HELP_EXAMPLES, "=IMNEG(\"1-j\")" },
237 { GNM_FUNC_HELP_END}
238 };
239
240 static GnmValue *
gnumeric_imneg(GnmFuncEvalInfo * ei,GnmValue const * const * argv)241 gnumeric_imneg (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
242 {
243 gnm_complex c;
244 char imunit;
245
246 if (value_get_as_complex (argv[0], &c, &imunit))
247 return value_new_error_NUM (ei->pos);
248
249 return value_new_complexv (GNM_CNEG (c), imunit);
250 }
251
252 /***************************************************************************/
253
254 static GnmFuncHelp const help_imcos[] = {
255 { GNM_FUNC_HELP_NAME, F_("IMCOS:the cosine of the complex number @{z}") },
256 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
257 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
258 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
259 { GNM_FUNC_HELP_EXAMPLES, "=IMCOS(\"1+j\")" },
260 { GNM_FUNC_HELP_SEEALSO, "IMSIN,IMTAN" },
261 { GNM_FUNC_HELP_END}
262 };
263
264
265 static GnmValue *
gnumeric_imcos(GnmFuncEvalInfo * ei,GnmValue const * const * argv)266 gnumeric_imcos (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
267 {
268 gnm_complex c;
269 char imunit;
270
271 if (value_get_as_complex (argv[0], &c, &imunit))
272 return value_new_error_NUM (ei->pos);
273
274 return value_new_complexv (GNM_CCOS (c), imunit);
275 }
276
277 /***************************************************************************/
278
279 static GnmFuncHelp const help_imtan[] = {
280 { GNM_FUNC_HELP_NAME, F_("IMTAN:the tangent of the complex number @{z}") },
281 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
282 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
283 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
284 { GNM_FUNC_HELP_EXAMPLES, "=IMTAN(\"2-j\")" },
285 { GNM_FUNC_HELP_SEEALSO, "IMSIN,IMCOS" },
286 { GNM_FUNC_HELP_END}
287 };
288
289
290 static GnmValue *
gnumeric_imtan(GnmFuncEvalInfo * ei,GnmValue const * const * argv)291 gnumeric_imtan (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
292 {
293 gnm_complex c;
294 char imunit;
295
296 if (value_get_as_complex (argv[0], &c, &imunit))
297 return value_new_error_NUM (ei->pos);
298
299 return value_new_complexv (GNM_CTAN (c), imunit);
300 }
301
302 /***************************************************************************/
303
304 static GnmFuncHelp const help_imsec[] = {
305 { GNM_FUNC_HELP_NAME, F_("IMSEC:the secant of the complex number @{z}") },
306 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
307 { GNM_FUNC_HELP_DESCRIPTION, F_("IMSEC(@{z}) = 1/IMCOS(@{z}).") },
308 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
309 { GNM_FUNC_HELP_EXAMPLES, "=IMSEC(\"2-j\")" },
310 { GNM_FUNC_HELP_SEEALSO, "IMCSC,IMCOT" },
311 { GNM_FUNC_HELP_END}
312 };
313
314
315 static GnmValue *
gnumeric_imsec(GnmFuncEvalInfo * ei,GnmValue const * const * argv)316 gnumeric_imsec (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
317 {
318 gnm_complex c;
319 char imunit;
320
321 if (value_get_as_complex (argv[0], &c, &imunit))
322 return value_new_error_NUM (ei->pos);
323
324 return value_new_complexv (GNM_CINV (GNM_CCOS (c)), imunit);
325 }
326
327 /***************************************************************************/
328
329 static GnmFuncHelp const help_imcsc[] = {
330 { GNM_FUNC_HELP_NAME, F_("IMCSC:the cosecant of the complex number @{z}") },
331 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
332 { GNM_FUNC_HELP_DESCRIPTION, F_("IMCSC(@{z}) = 1/IMSIN(@{z}).") },
333 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
334 { GNM_FUNC_HELP_EXAMPLES, "=IMCSC(\"2-j\")" },
335 { GNM_FUNC_HELP_SEEALSO, "IMSEC,IMCOT" },
336 { GNM_FUNC_HELP_END}
337 };
338
339 static GnmValue *
gnumeric_imcsc(GnmFuncEvalInfo * ei,GnmValue const * const * argv)340 gnumeric_imcsc (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
341 {
342 gnm_complex c;
343 char imunit;
344
345 if (value_get_as_complex (argv[0], &c, &imunit))
346 return value_new_error_NUM (ei->pos);
347
348 return value_new_complexv (GNM_CINV (GNM_CSIN (c)), imunit);
349 }
350
351 /***************************************************************************/
352
353 static GnmFuncHelp const help_imcot[] = {
354 { GNM_FUNC_HELP_NAME, F_("IMCOT:the cotangent of the complex number @{z}") },
355 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
356 { GNM_FUNC_HELP_DESCRIPTION, F_("IMCOT(@{z}) = IMCOS(@{z})/IMSIN(@{z}).") },
357 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
358 { GNM_FUNC_HELP_EXAMPLES, "=IMCOT(\"2-i\")" },
359 { GNM_FUNC_HELP_EXAMPLES, "=IMCOT(\"2+j\")" },
360 { GNM_FUNC_HELP_SEEALSO, "IMSEC,IMCSC" },
361 { GNM_FUNC_HELP_END}
362 };
363
364 static GnmValue *
gnumeric_imcot(GnmFuncEvalInfo * ei,GnmValue const * const * argv)365 gnumeric_imcot (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
366 {
367 gnm_complex c;
368 char imunit;
369
370 if (value_get_as_complex (argv[0], &c, &imunit))
371 return value_new_error_NUM (ei->pos);
372
373 return value_new_complexv (GNM_CINV (GNM_CTAN (c)), imunit);
374 }
375
376 /***************************************************************************/
377
378 static GnmFuncHelp const help_imexp[] = {
379 { GNM_FUNC_HELP_NAME, F_("IMEXP:the exponential of the complex number @{z}") },
380 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
381 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
382 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
383 { GNM_FUNC_HELP_EXAMPLES, "=IMEXP(\"2-i\")" },
384 { GNM_FUNC_HELP_EXAMPLES, "=IMEXP(\"2+j\")" },
385 { GNM_FUNC_HELP_SEEALSO, "IMLN" },
386 { GNM_FUNC_HELP_END}
387 };
388
389
390 static GnmValue *
gnumeric_imexp(GnmFuncEvalInfo * ei,GnmValue const * const * argv)391 gnumeric_imexp (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
392 {
393 gnm_complex c;
394 char imunit;
395
396 if (value_get_as_complex (argv[0], &c, &imunit))
397 return value_new_error_NUM (ei->pos);
398
399 return value_new_complexv (GNM_CEXP (c), imunit);
400 }
401
402 /***************************************************************************/
403
404 static GnmFuncHelp const help_imargument[] = {
405 { GNM_FUNC_HELP_NAME, F_("IMARGUMENT:the argument theta of the complex number @{z}") },
406 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
407 { GNM_FUNC_HELP_DESCRIPTION, F_("The argument theta of a complex number is its angle in radians from the real axis.") },
408 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
409 { GNM_FUNC_HELP_NOTE, F_("If @{z} is 0, 0 is returned. This is different from Excel which returns an error.") },
410 { GNM_FUNC_HELP_EXAMPLES, "=IMARGUMENT(\"2-j\")" },
411 { GNM_FUNC_HELP_EXAMPLES, "=IMARGUMENT(0)" },
412 { GNM_FUNC_HELP_END}
413 };
414
415 static GnmValue *
gnumeric_imargument(GnmFuncEvalInfo * ei,GnmValue const * const * argv)416 gnumeric_imargument (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
417 {
418 gnm_complex c;
419 char imunit;
420
421 if (value_get_as_complex (argv[0], &c, &imunit))
422 return value_new_error_NUM (ei->pos);
423
424 return value_new_float (GNM_CARG (c));
425 }
426
427 /***************************************************************************/
428
429 static GnmFuncHelp const help_imln[] = {
430 { GNM_FUNC_HELP_NAME, F_("IMLN:the natural logarithm of the complex number @{z}") },
431 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
432 { GNM_FUNC_HELP_DESCRIPTION, F_("The result will have an imaginary part between -\xcf\x80 and +\xcf\x80.\n"
433 "The natural logarithm is not uniquely defined on complex numbers. "
434 "You may need to add or subtract an even multiple of \xcf\x80 to the imaginary part.")},
435 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
436 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
437 { GNM_FUNC_HELP_EXAMPLES, "=IMLN(\"3-j\")" },
438 { GNM_FUNC_HELP_SEEALSO, "IMEXP,IMLOG2,IMLOG10" },
439 { GNM_FUNC_HELP_END}
440 };
441
442 static GnmValue *
gnumeric_imln(GnmFuncEvalInfo * ei,GnmValue const * const * argv)443 gnumeric_imln (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
444 {
445 gnm_complex c;
446 char imunit;
447
448 if (value_get_as_complex (argv[0], &c, &imunit))
449 return value_new_error_NUM (ei->pos);
450
451 return value_new_complexv (GNM_CLN (c), imunit);
452 }
453
454 /***************************************************************************/
455
456 static GnmFuncHelp const help_imlog2[] = {
457 { GNM_FUNC_HELP_NAME, F_("IMLOG2:the base-2 logarithm of the complex number @{z}") },
458 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
459 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
460 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
461 { GNM_FUNC_HELP_EXAMPLES, "=IMLOG2(\"3-j\")" },
462 { GNM_FUNC_HELP_SEEALSO, "IMLN,IMLOG10" },
463 { GNM_FUNC_HELP_END}
464 };
465
466
467 static GnmValue *
gnumeric_imlog2(GnmFuncEvalInfo * ei,GnmValue const * const * argv)468 gnumeric_imlog2 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
469 {
470 gnm_complex c;
471 char imunit;
472
473 if (value_get_as_complex (argv[0], &c, &imunit))
474 return value_new_error_NUM (ei->pos);
475
476 return value_new_complexv (GNM_CSCALE (GNM_CLN (c), 1 / M_LN2gnum), imunit);
477 }
478
479 /***************************************************************************/
480
481 static GnmFuncHelp const help_imlog10[] = {
482 { GNM_FUNC_HELP_NAME, F_("IMLOG10:the base-10 logarithm of the complex number @{z}") },
483 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
484 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
485 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
486 { GNM_FUNC_HELP_EXAMPLES, "=IMLOG10(\"3-j\")" },
487 { GNM_FUNC_HELP_SEEALSO, "IMLN,IMLOG2" },
488 { GNM_FUNC_HELP_END}
489 };
490
491 static GnmValue *
gnumeric_imlog10(GnmFuncEvalInfo * ei,GnmValue const * const * argv)492 gnumeric_imlog10 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
493 {
494 gnm_complex c;
495 char imunit;
496
497 if (value_get_as_complex (argv[0], &c, &imunit))
498 return value_new_error_NUM (ei->pos);
499
500 return value_new_complexv (GNM_CSCALE (GNM_CLN (c), M_LN10INVgnum), imunit);
501 }
502
503 /***************************************************************************/
504
505 static GnmFuncHelp const help_impower[] = {
506 { GNM_FUNC_HELP_NAME, F_("IMPOWER:the complex number @{z1} raised to the @{z2}th power") },
507 { GNM_FUNC_HELP_ARG, F_("z1:a complex number") },
508 { GNM_FUNC_HELP_ARG, F_("z2:a complex number") },
509 { GNM_FUNC_HELP_NOTE, F_("If @{z1} or @{z2} is not a valid complex number, #VALUE! is returned.") },
510 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
511 { GNM_FUNC_HELP_EXAMPLES, "=IMPOWER(\"4-j\",2)" },
512 { GNM_FUNC_HELP_SEEALSO, "IMSQRT" },
513 { GNM_FUNC_HELP_END}
514 };
515
516 static GnmValue *
gnumeric_impower(GnmFuncEvalInfo * ei,GnmValue const * const * argv)517 gnumeric_impower (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
518 {
519 gnm_complex a, b;
520 char imunit;
521
522 if (value_get_as_complex (argv[0], &a, &imunit))
523 return value_new_error_NUM (ei->pos);
524
525 if (value_get_as_complex (argv[1], &b, &imunit))
526 return value_new_error_NUM (ei->pos);
527
528 if (GNM_CZEROP (a) && GNM_CZEROP (b))
529 return value_new_error_DIV0 (ei->pos);
530
531 return value_new_complexv (GNM_CPOW (a, b), imunit);
532 }
533
534 /***************************************************************************/
535
536 static GnmFuncHelp const help_imdiv[] = {
537 { GNM_FUNC_HELP_NAME, F_("IMDIV:the quotient of two complex numbers @{z1}/@{z2}") },
538 { GNM_FUNC_HELP_ARG, F_("z1:a complex number") },
539 { GNM_FUNC_HELP_ARG, F_("z2:a complex number") },
540 { GNM_FUNC_HELP_NOTE, F_("If @{z1} or @{z2} is not a valid complex number, #VALUE! is returned.") },
541 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
542 { GNM_FUNC_HELP_EXAMPLES, "=IMDIV(\"2-j\",\"2+j\")" },
543 { GNM_FUNC_HELP_SEEALSO, "IMPRODUCT" },
544 { GNM_FUNC_HELP_END}
545 };
546
547
548 static GnmValue *
gnumeric_imdiv(GnmFuncEvalInfo * ei,GnmValue const * const * argv)549 gnumeric_imdiv (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
550 {
551 gnm_complex a, b;
552 char imunit;
553
554 if (value_get_as_complex (argv[0], &a, &imunit))
555 return value_new_error_NUM (ei->pos);
556
557 if (value_get_as_complex (argv[1], &b, &imunit))
558 return value_new_error_NUM (ei->pos);
559
560 if (GNM_CZEROP (b))
561 return value_new_error_DIV0 (ei->pos);
562
563 return value_new_complexv (GNM_CDIV (a, b), imunit);
564 }
565
566 /***************************************************************************/
567
568 static GnmFuncHelp const help_imsin[] = {
569 { GNM_FUNC_HELP_NAME, F_("IMSIN:the sine of the complex number @{z}") },
570 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
571 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
572 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
573 { GNM_FUNC_HELP_EXAMPLES, "=IMSIN(\"1+j\")" },
574 { GNM_FUNC_HELP_SEEALSO, "IMCOS,IMTAN" },
575 { GNM_FUNC_HELP_END}
576 };
577
578 static GnmValue *
gnumeric_imsin(GnmFuncEvalInfo * ei,GnmValue const * const * argv)579 gnumeric_imsin (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
580 {
581 gnm_complex c;
582 char imunit;
583
584 if (value_get_as_complex (argv[0], &c, &imunit))
585 return value_new_error_NUM (ei->pos);
586
587 return value_new_complexv (GNM_CSIN (c), imunit);
588 }
589
590 /***************************************************************************/
591
592 static GnmFuncHelp const help_imsinh[] = {
593 { GNM_FUNC_HELP_NAME, F_("IMSINH:the hyperbolic sine of the complex number @{z}") },
594 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
595 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
596 { GNM_FUNC_HELP_EXAMPLES, "=IMSINH(\"1+j\")" },
597 { GNM_FUNC_HELP_SEEALSO, "IMCOSH,IMTANH" },
598 { GNM_FUNC_HELP_END}
599 };
600
601 static GnmValue *
gnumeric_imsinh(GnmFuncEvalInfo * ei,GnmValue const * const * argv)602 gnumeric_imsinh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
603 {
604 gnm_complex c;
605 char imunit;
606
607 if (value_get_as_complex (argv[0], &c, &imunit))
608 return value_new_error_NUM (ei->pos);
609
610 return value_new_complexv (GNM_CSINH (c), imunit);
611 }
612
613 /***************************************************************************/
614
615 static GnmFuncHelp const help_imcosh[] = {
616 { GNM_FUNC_HELP_NAME, F_("IMCOSH:the hyperbolic cosine of the complex number @{z}") },
617 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
618 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
619 { GNM_FUNC_HELP_EXAMPLES, "=IMCOSH(\"1+j\")" },
620 { GNM_FUNC_HELP_SEEALSO, "IMSINH,IMTANH" },
621 { GNM_FUNC_HELP_END}
622 };
623
624
625 static GnmValue *
gnumeric_imcosh(GnmFuncEvalInfo * ei,GnmValue const * const * argv)626 gnumeric_imcosh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
627 {
628 gnm_complex c;
629 char imunit;
630
631 if (value_get_as_complex (argv[0], &c, &imunit))
632 return value_new_error_NUM (ei->pos);
633
634 return value_new_complexv (GNM_CCOSH (c), imunit);
635 }
636
637 /***************************************************************************/
638
639 static GnmFuncHelp const help_imtanh[] = {
640 { GNM_FUNC_HELP_NAME, F_("IMTANH:the hyperbolic tangent of the complex number @{z}") },
641 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
642 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
643 { GNM_FUNC_HELP_EXAMPLES, "=IMTANH(\"1+j\")" },
644 { GNM_FUNC_HELP_SEEALSO, "IMSINH,IMCOSH" },
645 { GNM_FUNC_HELP_END}
646 };
647
648
649 static GnmValue *
gnumeric_imtanh(GnmFuncEvalInfo * ei,GnmValue const * const * argv)650 gnumeric_imtanh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
651 {
652 gnm_complex c;
653 char imunit;
654
655 if (value_get_as_complex (argv[0], &c, &imunit))
656 return value_new_error_NUM (ei->pos);
657
658 return value_new_complexv (GNM_CTANH (c), imunit);
659 }
660
661 /***************************************************************************/
662
663 static GnmFuncHelp const help_imsech[] = {
664 { GNM_FUNC_HELP_NAME, F_("IMSECH:the hyperbolic secant of the complex number @{z}") },
665 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
666 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
667 { GNM_FUNC_HELP_EXAMPLES, "=IMSECH(\"1+j\")" },
668 { GNM_FUNC_HELP_SEEALSO, "IMCSCH,IMCOTH" },
669 { GNM_FUNC_HELP_END}
670 };
671
672 static GnmValue *
gnumeric_imsech(GnmFuncEvalInfo * ei,GnmValue const * const * argv)673 gnumeric_imsech (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
674 {
675 gnm_complex c;
676 char imunit;
677
678 if (value_get_as_complex (argv[0], &c, &imunit))
679 return value_new_error_NUM (ei->pos);
680
681 return value_new_complexv (GNM_CSECH (c), imunit);
682 }
683
684 /***************************************************************************/
685
686 static GnmFuncHelp const help_imcsch[] = {
687 { GNM_FUNC_HELP_NAME, F_("IMCSCH:the hyperbolic cosecant of the complex number @{z}") },
688 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
689 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
690 { GNM_FUNC_HELP_EXAMPLES, "=IMCSCH(\"1+j\")" },
691 { GNM_FUNC_HELP_SEEALSO, "IMSECH,IMCOTH" },
692 { GNM_FUNC_HELP_END}
693 };
694
695
696 static GnmValue *
gnumeric_imcsch(GnmFuncEvalInfo * ei,GnmValue const * const * argv)697 gnumeric_imcsch (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
698 {
699 gnm_complex c;
700 char imunit;
701
702 if (value_get_as_complex (argv[0], &c, &imunit))
703 return value_new_error_NUM (ei->pos);
704
705 return value_new_complexv (GNM_CCSCH (c), imunit);
706 }
707
708 /***************************************************************************/
709
710 static GnmFuncHelp const help_imcoth[] = {
711 { GNM_FUNC_HELP_NAME, F_("IMCOTH:the hyperbolic cotangent of the complex number @{z}") },
712 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
713 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
714 { GNM_FUNC_HELP_EXAMPLES, "=IMCOTH(\"1+j\")" },
715 { GNM_FUNC_HELP_SEEALSO, "IMSECH,IMCSCH" },
716 { GNM_FUNC_HELP_END}
717 };
718
719 static GnmValue *
gnumeric_imcoth(GnmFuncEvalInfo * ei,GnmValue const * const * argv)720 gnumeric_imcoth (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
721 {
722 gnm_complex c;
723 char imunit;
724
725 if (value_get_as_complex (argv[0], &c, &imunit))
726 return value_new_error_NUM (ei->pos);
727
728 return value_new_complexv (GNM_CCOTH (c), imunit);
729 }
730
731 /***************************************************************************/
732
733 static GnmFuncHelp const help_imarcsin[] = {
734 { GNM_FUNC_HELP_NAME, F_("IMARCSIN:the complex arcsine of the complex number @{z}") },
735 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
736 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCSIN returns the complex arcsine of the complex number "
737 "@{z}. The branch cuts are on the real axis, less than -1 and greater than 1.") },
738 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
739 { GNM_FUNC_HELP_EXAMPLES, "=IMARCSIN(\"1+j\")" },
740 { GNM_FUNC_HELP_SEEALSO, "IMARCCOS,IMARCTAN" },
741 { GNM_FUNC_HELP_END}
742 };
743
744
745 static GnmValue *
gnumeric_imarcsin(GnmFuncEvalInfo * ei,GnmValue const * const * argv)746 gnumeric_imarcsin (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
747 {
748 gnm_complex c;
749 char imunit;
750
751 if (value_get_as_complex (argv[0], &c, &imunit))
752 return value_new_error_NUM (ei->pos);
753
754 return value_new_complexv (GNM_CARCSIN (c), imunit);
755 }
756
757 /***************************************************************************/
758
759 static GnmFuncHelp const help_imarccos[] = {
760 { GNM_FUNC_HELP_NAME, F_("IMARCCOS:the complex arccosine of the complex number") },
761 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
762 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCCOS returns the complex arccosine of the complex number "
763 "@{z}. The branch cuts are on the real axis, less than -1 and greater than 1.") },
764 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
765 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCOS(\"1+j\")" },
766 { GNM_FUNC_HELP_SEEALSO, "IMARCSIN,IMARCTAN" },
767 { GNM_FUNC_HELP_END}
768 };
769
770
771 static GnmValue *
gnumeric_imarccos(GnmFuncEvalInfo * ei,GnmValue const * const * argv)772 gnumeric_imarccos (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
773 {
774 gnm_complex c;
775 char imunit;
776
777 if (value_get_as_complex (argv[0], &c, &imunit))
778 return value_new_error_NUM (ei->pos);
779
780 return value_new_complexv (GNM_CARCCOS (c), imunit);
781 }
782
783 /***************************************************************************/
784
785 static GnmFuncHelp const help_imarctan[] = {
786 { GNM_FUNC_HELP_NAME, F_("IMARCTAN:the complex arctangent of the complex number") },
787 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
788 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCTAN returns the complex arctangent of the complex number "
789 "@{z}. The branch cuts are on the imaginary axis, below -i and above i.") },
790 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
791 { GNM_FUNC_HELP_EXAMPLES, "=IMARCTAN(\"1+j\")" },
792 { GNM_FUNC_HELP_SEEALSO, "IMARCSIN,IMARCCOS" },
793 { GNM_FUNC_HELP_END}
794 };
795
796
797 static GnmValue *
gnumeric_imarctan(GnmFuncEvalInfo * ei,GnmValue const * const * argv)798 gnumeric_imarctan (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
799 {
800 gnm_complex c;
801 char imunit;
802
803 if (value_get_as_complex (argv[0], &c, &imunit))
804 return value_new_error_NUM (ei->pos);
805
806 return value_new_complexv (GNM_CARCTAN (c), imunit);
807 }
808
809 /***************************************************************************/
810
811 static GnmFuncHelp const help_imarcsec[] = {
812 { GNM_FUNC_HELP_NAME, F_("IMARCSEC:the complex arcsecant of the complex number @{z}") },
813 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
814 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
815 { GNM_FUNC_HELP_EXAMPLES, "=IMARCSEC(\"1+j\")" },
816 { GNM_FUNC_HELP_SEEALSO, "IMARCCSC,IMARCCOT" },
817 { GNM_FUNC_HELP_END}
818 };
819
820 static GnmValue *
gnumeric_imarcsec(GnmFuncEvalInfo * ei,GnmValue const * const * argv)821 gnumeric_imarcsec (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
822 {
823 gnm_complex c;
824 char imunit;
825
826 if (value_get_as_complex (argv[0], &c, &imunit))
827 return value_new_error_NUM (ei->pos);
828
829 return value_new_complexv (GNM_CARCSEC (c), imunit);
830 }
831
832 /***************************************************************************/
833
834 static GnmFuncHelp const help_imarccsc[] = {
835 { GNM_FUNC_HELP_NAME, F_("IMARCCSC:the complex arccosecant of the complex number @{z}") },
836 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
837 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
838 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCSC(\"1+j\")" },
839 { GNM_FUNC_HELP_SEEALSO, "IMARCSEC,IMARCCOT" },
840 { GNM_FUNC_HELP_END}
841 };
842
843
844 static GnmValue *
gnumeric_imarccsc(GnmFuncEvalInfo * ei,GnmValue const * const * argv)845 gnumeric_imarccsc (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
846 {
847 gnm_complex c;
848 char imunit;
849
850 if (value_get_as_complex (argv[0], &c, &imunit))
851 return value_new_error_NUM (ei->pos);
852
853 return value_new_complexv (GNM_CARCCSC (c), imunit);
854 }
855
856 /***************************************************************************/
857
858 static GnmFuncHelp const help_imarccot[] = {
859 { GNM_FUNC_HELP_NAME, F_("IMARCCOT:the complex arccotangent of the complex number @{z}") },
860 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
861 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
862 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCOT(\"1+j\")" },
863 { GNM_FUNC_HELP_SEEALSO, "IMARCSEC,IMARCCSC" },
864 { GNM_FUNC_HELP_END}
865 };
866
867 static GnmValue *
gnumeric_imarccot(GnmFuncEvalInfo * ei,GnmValue const * const * argv)868 gnumeric_imarccot (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
869 {
870 gnm_complex c;
871 char imunit;
872
873 if (value_get_as_complex (argv[0], &c, &imunit))
874 return value_new_error_NUM (ei->pos);
875
876 return value_new_complexv (GNM_CARCCOT (c), imunit);
877 }
878
879 /***************************************************************************/
880
881 static GnmFuncHelp const help_imarcsinh[] = {
882 { GNM_FUNC_HELP_NAME, F_("IMARCSINH:the complex hyperbolic arcsine of the complex number @{z}") },
883 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
884 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCSINH returns the complex hyperbolic arcsine of the complex number @{z}. "
885 " The branch cuts are on the imaginary axis, below -i and above i.") },
886 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
887 { GNM_FUNC_HELP_EXAMPLES, "=IMARCSINH(\"1+j\")" },
888 { GNM_FUNC_HELP_SEEALSO, "IMARCCOSH,IMARCTANH" },
889 { GNM_FUNC_HELP_END}
890 };
891
892
893 static GnmValue *
gnumeric_imarcsinh(GnmFuncEvalInfo * ei,GnmValue const * const * argv)894 gnumeric_imarcsinh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
895 {
896 gnm_complex c;
897 char imunit;
898
899 if (value_get_as_complex (argv[0], &c, &imunit))
900 return value_new_error_NUM (ei->pos);
901
902 return value_new_complexv (GNM_CARCSINH (c), imunit);
903 }
904
905 /***************************************************************************/
906
907 static GnmFuncHelp const help_imarccosh[] = {
908 { GNM_FUNC_HELP_NAME, F_("IMARCCOSH:the complex hyperbolic arccosine of the complex number @{z}") },
909 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
910 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCCOSH returns the complex hyperbolic arccosine of the "
911 "complex number @{z}. The branch cut is on the real "
912 "axis, less than 1.") },
913 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
914 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCOSH(\"1+j\")" },
915 { GNM_FUNC_HELP_SEEALSO, "IMARCSINH,IMARCTANH" },
916 { GNM_FUNC_HELP_END}
917 };
918
919
920 static GnmValue *
gnumeric_imarccosh(GnmFuncEvalInfo * ei,GnmValue const * const * argv)921 gnumeric_imarccosh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
922 {
923 gnm_complex c;
924 char imunit;
925
926 if (value_get_as_complex (argv[0], &c, &imunit))
927 return value_new_error_NUM (ei->pos);
928
929 return value_new_complexv (GNM_CARCCOSH (c), imunit);
930 }
931
932 /***************************************************************************/
933
934 static GnmFuncHelp const help_imarctanh[] = {
935 { GNM_FUNC_HELP_NAME, F_("IMARCTANH:the complex hyperbolic arctangent of the complex number @{z}") },
936 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
937 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCTANH returns the complex hyperbolic arctangent of the "
938 "complex number @{z}. The branch cuts are on the "
939 "real axis, less than -1 and greater than 1.") },
940 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
941 { GNM_FUNC_HELP_EXAMPLES, "=IMARCTANH(\"1+j\")" },
942 { GNM_FUNC_HELP_SEEALSO, "IMARCSINH,IMARCCOSH" },
943 { GNM_FUNC_HELP_END}
944 };
945
946
947 static GnmValue *
gnumeric_imarctanh(GnmFuncEvalInfo * ei,GnmValue const * const * argv)948 gnumeric_imarctanh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
949 {
950 gnm_complex c;
951 char imunit;
952
953 if (value_get_as_complex (argv[0], &c, &imunit))
954 return value_new_error_NUM (ei->pos);
955
956 return value_new_complexv (GNM_CARCTANH (c), imunit);
957 }
958
959 /***************************************************************************/
960
961 static GnmFuncHelp const help_imarcsech[] = {
962 { GNM_FUNC_HELP_NAME, F_("IMARCSECH:the complex hyperbolic arcsecant of the complex number @{z}") },
963 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
964 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
965 { GNM_FUNC_HELP_EXAMPLES, "=IMARCSECH(\"1+j\")" },
966 { GNM_FUNC_HELP_SEEALSO, "IMARCCSCH,IMARCCOTH" },
967 { GNM_FUNC_HELP_END}
968 };
969
970 static GnmValue *
gnumeric_imarcsech(GnmFuncEvalInfo * ei,GnmValue const * const * argv)971 gnumeric_imarcsech (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
972 {
973 gnm_complex c;
974 char imunit;
975
976 if (value_get_as_complex (argv[0], &c, &imunit))
977 return value_new_error_NUM (ei->pos);
978
979 return value_new_complexv (GNM_CARCSECH (c), imunit);
980 }
981
982 /***************************************************************************/
983
984 static GnmFuncHelp const help_imarccsch[] = {
985 { GNM_FUNC_HELP_NAME, F_("IMARCCSCH:the complex hyperbolic arccosecant of the complex number @{z}") },
986 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
987 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
988 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCSCH(\"1+j\")" },
989 { GNM_FUNC_HELP_SEEALSO, "IMARCSECH,IMARCCOTH" },
990 { GNM_FUNC_HELP_END}
991 };
992
993
994 static GnmValue *
gnumeric_imarccsch(GnmFuncEvalInfo * ei,GnmValue const * const * argv)995 gnumeric_imarccsch (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
996 {
997 gnm_complex c;
998 char imunit;
999
1000 if (value_get_as_complex (argv[0], &c, &imunit))
1001 return value_new_error_NUM (ei->pos);
1002
1003 return value_new_complexv (GNM_CARCCSCH (c), imunit);
1004 }
1005
1006 /***************************************************************************/
1007
1008 static GnmFuncHelp const help_imarccoth[] = {
1009 { GNM_FUNC_HELP_NAME, F_("IMARCCOTH:the complex hyperbolic arccotangent of the complex number @{z}") },
1010 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
1011 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
1012 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCOTH(\"1+j\")" },
1013 { GNM_FUNC_HELP_SEEALSO, "IMARCSECH,IMARCCSCH" },
1014 { GNM_FUNC_HELP_END}
1015 };
1016
1017
1018 static GnmValue *
gnumeric_imarccoth(GnmFuncEvalInfo * ei,GnmValue const * const * argv)1019 gnumeric_imarccoth (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1020 {
1021 gnm_complex c;
1022 char imunit;
1023
1024 if (value_get_as_complex (argv[0], &c, &imunit))
1025 return value_new_error_NUM (ei->pos);
1026
1027 return value_new_complexv (GNM_CARCCOTH (c), imunit);
1028 }
1029
1030 /***************************************************************************/
1031
1032 static GnmFuncHelp const help_imsqrt[] = {
1033 { GNM_FUNC_HELP_NAME, F_("IMSQRT:the square root of the complex number @{z}") },
1034 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
1035 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
1036 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
1037 { GNM_FUNC_HELP_EXAMPLES, "=IMSQRT(\"1+j\")" },
1038 { GNM_FUNC_HELP_SEEALSO, "IMPOWER" },
1039 { GNM_FUNC_HELP_END}
1040 };
1041
1042
1043 static GnmValue *
gnumeric_imsqrt(GnmFuncEvalInfo * ei,GnmValue const * const * argv)1044 gnumeric_imsqrt (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1045 {
1046 gnm_complex c;
1047 char imunit;
1048
1049 if (value_get_as_complex (argv[0], &c, &imunit))
1050 return value_new_error_NUM (ei->pos);
1051
1052 return value_new_complexv (GNM_CSQRT (c), imunit);
1053 }
1054
1055 /***************************************************************************/
1056
1057 static GnmFuncHelp const help_imfact[] = {
1058 { GNM_FUNC_HELP_NAME, F_("IMFACT:the factorial of the complex number @{z}") },
1059 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
1060 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
1061 { GNM_FUNC_HELP_EXAMPLES, "=IMFACT(\"1+j\")" },
1062 { GNM_FUNC_HELP_SEEALSO, "IMGAMMA" },
1063 { GNM_FUNC_HELP_END}
1064 };
1065
1066
1067 static GnmValue *
gnumeric_imfact(GnmFuncEvalInfo * ei,GnmValue const * const * argv)1068 gnumeric_imfact (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1069 {
1070 gnm_complex c;
1071 char imunit;
1072
1073 if (value_get_as_complex (argv[0], &c, &imunit))
1074 return value_new_error_NUM (ei->pos);
1075
1076 return value_new_complexv (gnm_complex_fact (c, NULL), imunit);
1077 }
1078
1079 /***************************************************************************/
1080
1081 static GnmFuncHelp const help_imgamma[] = {
1082 { GNM_FUNC_HELP_NAME, F_("IMGAMMA:the gamma function of the complex number @{z}") },
1083 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
1084 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
1085 { GNM_FUNC_HELP_EXAMPLES, "=IMGAMMA(\"1+j\")" },
1086 { GNM_FUNC_HELP_SEEALSO, "IMGAMMA" },
1087 { GNM_FUNC_HELP_END}
1088 };
1089
1090
1091 static GnmValue *
gnumeric_imgamma(GnmFuncEvalInfo * ei,GnmValue const * const * argv)1092 gnumeric_imgamma (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1093 {
1094 gnm_complex c;
1095 char imunit;
1096
1097 if (value_get_as_complex (argv[0], &c, &imunit))
1098 return value_new_error_NUM (ei->pos);
1099
1100 return value_new_complexv (gnm_complex_gamma (c, NULL), imunit);
1101 }
1102
1103 /***************************************************************************/
1104
1105 static GnmFuncHelp const help_imigamma[] = {
1106 { GNM_FUNC_HELP_NAME, F_("IMIGAMMA:the incomplete Gamma function")},
1107 { GNM_FUNC_HELP_ARG, F_("a:a complex number")},
1108 { GNM_FUNC_HELP_ARG, F_("z:a complex number")},
1109 { GNM_FUNC_HELP_ARG, F_("lower:if true (the default), the lower incomplete gamma function, otherwise the upper incomplete gamma function")},
1110 { GNM_FUNC_HELP_ARG, F_("regularize:if true (the default), the regularized version of the incomplete gamma function")},
1111 { GNM_FUNC_HELP_NOTE, F_("The regularized incomplete gamma function is the unregularized incomplete gamma function divided by GAMMA(@{a}).") },
1112 { GNM_FUNC_HELP_EXAMPLES, "=IMIGAMMA(2.5,-1.8,TRUE,TRUE)" },
1113 { GNM_FUNC_HELP_EXAMPLES, "=IMIGAMMA(2.5,-1.8,TRUE,TRUE)" },
1114 { GNM_FUNC_HELP_SEEALSO, "GAMMA,IMIGAMMA"},
1115 { GNM_FUNC_HELP_END}
1116 };
1117
1118
1119 static GnmValue *
gnumeric_imigamma(GnmFuncEvalInfo * ei,GnmValue const * const * argv)1120 gnumeric_imigamma (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1121 {
1122 gnm_complex a, z;
1123 char imunit;
1124 gboolean lower = argv[2] ? value_get_as_checked_bool (argv[2]) : TRUE;
1125 gboolean reg = argv[3] ? value_get_as_checked_bool (argv[3]) : TRUE;
1126
1127 if (value_get_as_complex (argv[0], &a, &imunit))
1128 return value_new_error_NUM (ei->pos);
1129 if (value_get_as_complex (argv[1], &z, &imunit))
1130 return value_new_error_NUM (ei->pos);
1131
1132 return value_new_complexv (gnm_complex_igamma (a, z, lower, reg), imunit);
1133 }
1134
1135 /***************************************************************************/
1136
1137 static GnmFuncHelp const help_imsub[] = {
1138 { GNM_FUNC_HELP_NAME, F_("IMSUB:the difference of two complex numbers") },
1139 { GNM_FUNC_HELP_ARG, F_("z1:a complex number") },
1140 { GNM_FUNC_HELP_ARG, F_("z2:a complex number") },
1141 { GNM_FUNC_HELP_NOTE, F_("If @{z1} or @{z2} is not a valid complex number, #VALUE! is returned.") },
1142 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
1143 { GNM_FUNC_HELP_EXAMPLES, "=IMSUB(\"3-j\",\"2+j\")" },
1144 { GNM_FUNC_HELP_SEEALSO, "IMSUM" },
1145 { GNM_FUNC_HELP_END}
1146 };
1147
1148
1149 static GnmValue *
gnumeric_imsub(GnmFuncEvalInfo * ei,GnmValue const * const * argv)1150 gnumeric_imsub (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1151 {
1152 gnm_complex a, b;
1153 char imunit;
1154
1155 if (value_get_as_complex (argv[0], &a, &imunit))
1156 return value_new_error_NUM (ei->pos);
1157
1158 if (value_get_as_complex (argv[1], &b, &imunit))
1159 return value_new_error_NUM (ei->pos);
1160
1161 return value_new_complexv (GNM_CSUB (a, b), imunit);
1162 }
1163
1164 /***************************************************************************/
1165
1166 static GnmFuncHelp const help_improduct[] = {
1167 { GNM_FUNC_HELP_NAME, F_("IMPRODUCT:the product of the given complex numbers") },
1168 { GNM_FUNC_HELP_ARG, F_("z1:a complex number") },
1169 { GNM_FUNC_HELP_ARG, F_("z2:a complex number") },
1170 { GNM_FUNC_HELP_NOTE, F_("If any of @{z1}, @{z2},... is not a valid complex number, #VALUE! is returned.") },
1171 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
1172 { GNM_FUNC_HELP_EXAMPLES, "=IMPRODUCT(\"2-j\",\"4-2j\")" },
1173 { GNM_FUNC_HELP_SEEALSO, "IMDIV" },
1174 { GNM_FUNC_HELP_END}
1175 };
1176
1177
1178 typedef enum {
1179 Improduct, Imsum
1180 } eng_imoper_type_t;
1181
1182 typedef struct {
1183 gnm_complex res;
1184 char imunit;
1185 eng_imoper_type_t type;
1186 } eng_imoper_t;
1187
1188 static GnmValue *
callback_function_imoper(GnmEvalPos const * ep,GnmValue const * value,void * closure)1189 callback_function_imoper (GnmEvalPos const *ep, GnmValue const *value, void *closure)
1190 {
1191 eng_imoper_t *result = closure;
1192 gnm_complex c;
1193 char *imptr, dummy;
1194
1195 imptr = VALUE_IS_NUMBER (value) ? &dummy : &result->imunit;
1196 if (value_get_as_complex (value, &c, imptr))
1197 return value_new_error_NUM (ep);
1198
1199 switch (result->type) {
1200 case Improduct:
1201 result->res = GNM_CMUL (result->res, c);
1202 break;
1203 case Imsum:
1204 result->res = GNM_CADD (result->res, c);
1205 break;
1206 default:
1207 abort ();
1208 }
1209
1210 return NULL;
1211 }
1212
1213 static GnmValue *
gnumeric_improduct(GnmFuncEvalInfo * ei,int argc,GnmExprConstPtr const * argv)1214 gnumeric_improduct (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
1215 {
1216 GnmValue *v;
1217 eng_imoper_t p;
1218
1219 p.type = Improduct;
1220 p.imunit = 'j';
1221 p.res = GNM_C1;
1222
1223 v = function_iterate_argument_values
1224 (ei->pos, callback_function_imoper, &p,
1225 argc, argv, TRUE, CELL_ITER_IGNORE_BLANK);
1226
1227 if (v != NULL)
1228 return v;
1229
1230 return value_new_complexv (p.res, p.imunit);
1231 }
1232
1233 /***************************************************************************/
1234
1235 static GnmFuncHelp const help_imsum[] = {
1236 { GNM_FUNC_HELP_NAME, F_("IMSUM:the sum of the given complex numbers") },
1237 { GNM_FUNC_HELP_ARG, F_("z1:a complex number") },
1238 { GNM_FUNC_HELP_ARG, F_("z2:a complex number") },
1239 { GNM_FUNC_HELP_NOTE, F_("If any of @{z1}, @{z2},... is not a valid complex number, #VALUE! is returned.") },
1240 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
1241 { GNM_FUNC_HELP_EXAMPLES, "=IMSUM(\"2-4j\",\"9-j\")" },
1242 { GNM_FUNC_HELP_SEEALSO, "IMSUB" },
1243 { GNM_FUNC_HELP_END}
1244 };
1245
1246
1247 static GnmValue *
gnumeric_imsum(GnmFuncEvalInfo * ei,int argc,GnmExprConstPtr const * argv)1248 gnumeric_imsum (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
1249 {
1250 GnmValue *v;
1251 eng_imoper_t p;
1252
1253 p.type = Imsum;
1254 p.imunit = 'j';
1255 p.res = GNM_C0;
1256
1257 v = function_iterate_argument_values
1258 (ei->pos, callback_function_imoper, &p,
1259 argc, argv, TRUE, CELL_ITER_IGNORE_BLANK);
1260
1261 if (v != NULL)
1262 return v;
1263
1264 return value_new_complexv (p.res, p.imunit);
1265 }
1266
1267 /***************************************************************************/
1268
1269 GnmFuncDescriptor const complex_functions[] = {
1270 { "complex", "ff|s", help_complex,
1271 gnumeric_complex, NULL,
1272 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1273 { "imabs", "S", help_imabs,
1274 gnumeric_imabs, NULL,
1275 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1276 { "imaginary", "S", help_imaginary,
1277 gnumeric_imaginary, NULL,
1278 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1279 { "imargument", "S", help_imargument,
1280 gnumeric_imargument, NULL,
1281 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1282 { "imconjugate", "S", help_imconjugate,
1283 gnumeric_imconjugate, NULL,
1284 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1285 { "imcos", "S", help_imcos,
1286 gnumeric_imcos, NULL,
1287 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1288 { "imdiv", "SS", help_imdiv,
1289 gnumeric_imdiv, NULL,
1290 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1291 { "imexp", "S", help_imexp,
1292 gnumeric_imexp, NULL,
1293 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1294 { "imln", "S", help_imln,
1295 gnumeric_imln, NULL,
1296 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1297 { "imlog10", "S", help_imlog10,
1298 gnumeric_imlog10, NULL,
1299 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1300 { "imlog2", "S", help_imlog2,
1301 gnumeric_imlog2, NULL,
1302 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1303 { "impower", "SS", help_impower,
1304 gnumeric_impower, NULL,
1305 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1306 { "imreal", "S", help_imreal,
1307 gnumeric_imreal, NULL,
1308 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1309 { "imsin", "S", help_imsin,
1310 gnumeric_imsin, NULL,
1311 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1312 { "imsqrt", "S", help_imsqrt,
1313 gnumeric_imsqrt, NULL,
1314 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1315 { "imsub", "SS", help_imsub,
1316 gnumeric_imsub, NULL,
1317 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1318 { "imsum", NULL, help_imsum,
1319 NULL, gnumeric_imsum,
1320 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1321
1322 { "iminv", "S", help_iminv,
1323 gnumeric_iminv, NULL,
1324 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
1325 { "imneg", "S", help_imneg,
1326 gnumeric_imneg, NULL,
1327 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1328 { "imtan", "S", help_imtan,
1329 gnumeric_imtan, NULL,
1330 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1331 { "improduct", NULL, help_improduct,
1332 NULL, gnumeric_improduct,
1333 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1334 { "imsec", "S", help_imsec,
1335 gnumeric_imsec, NULL,
1336 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1337 { "imcsc", "S", help_imcsc,
1338 gnumeric_imcsc, NULL,
1339 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1340 { "imcot", "S", help_imcot,
1341 gnumeric_imcot, NULL,
1342 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1343 { "imsinh", "S", help_imsinh,
1344 gnumeric_imsinh, NULL,
1345 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1346 { "imcosh", "S", help_imcosh,
1347 gnumeric_imcosh, NULL,
1348 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1349 { "imtanh", "S", help_imtanh,
1350 gnumeric_imtanh, NULL,
1351 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1352 { "imsech", "S", help_imsech,
1353 gnumeric_imsech, NULL,
1354 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1355 { "imcsch", "S", help_imcsch,
1356 gnumeric_imcsch, NULL,
1357 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1358 { "imcoth", "S", help_imcoth,
1359 gnumeric_imcoth, NULL,
1360 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1361 { "imarcsin", "S", help_imarcsin,
1362 gnumeric_imarcsin, NULL,
1363 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1364 { "imarccos", "S", help_imarccos,
1365 gnumeric_imarccos, NULL,
1366 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1367 { "imarctan", "S", help_imarctan,
1368 gnumeric_imarctan, NULL,
1369 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1370 { "imarcsec", "S", help_imarcsec,
1371 gnumeric_imarcsec, NULL,
1372 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1373 { "imarccsc", "S", help_imarccsc,
1374 gnumeric_imarccsc, NULL,
1375 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1376 { "imarccot", "S", help_imarccot,
1377 gnumeric_imarccot, NULL,
1378 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1379 { "imarcsinh", "S", help_imarcsinh,
1380 gnumeric_imarcsinh, NULL,
1381 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1382 { "imarccosh", "S", help_imarccosh,
1383 gnumeric_imarccosh, NULL,
1384 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1385 { "imarctanh", "S", help_imarctanh,
1386 gnumeric_imarctanh, NULL,
1387 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1388 { "imarcsech", "S", help_imarcsech,
1389 gnumeric_imarcsech, NULL,
1390 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1391 { "imarccsch", "S", help_imarccsch,
1392 gnumeric_imarccsch, NULL,
1393 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1394 { "imarccoth", "S", help_imarccoth,
1395 gnumeric_imarccoth, NULL,
1396 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1397
1398 { "imfact", "S", help_imfact,
1399 gnumeric_imfact, NULL,
1400 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1401 { "imgamma", "S", help_imgamma,
1402 gnumeric_imgamma, NULL,
1403 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1404 { "imigamma", "SS|bb", help_imigamma,
1405 gnumeric_imigamma, NULL,
1406 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
1407
1408 {NULL}
1409 };
1410