Undo: fix problem with col widths after paste undo.
[gnumeric.git] / plugins / fn-complex / functions.c
blob6119d3c2c056dde28aed3fd1b226eaae5f175f20
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * fn-complex.c: Built in complex number functions and functions registration
5 * Authors:
6 * Michael Meeks <michael@ximian.com>
7 * Jukka-Pekka Iivonen (iivonen@iki.fi)
8 * Morten Welinder (terra@gnome.org)
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <https://www.gnu.org/licenses/>.
24 #include <gnumeric-config.h>
25 #include <gnumeric.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <func.h>
30 #include <complex.h>
31 #include <sf-gamma.h>
32 #include <parse-util.h>
33 #include <cell.h>
34 #include <expr.h>
35 #include <value.h>
36 #include <mathfunc.h>
37 #include <gnm-i18n.h>
39 #include <goffice/goffice.h>
40 #include <gnm-plugin.h>
41 #include "gsl-complex.h"
44 GNM_PLUGIN_MODULE_HEADER;
46 /* Converts a complex number string into its coefficients. Returns 0 if ok,
47 * 1 if an error occurred.
49 static int
50 value_get_as_complex (GnmValue const *val, gnm_complex *res, char *imunit)
52 if (VALUE_IS_NUMBER (val)) {
53 *res = GNM_CREAL (value_get_as_float (val));
54 *imunit = 'i';
55 return 0;
56 } else {
57 return gnm_complex_from_string (res,
58 value_peek_string (val),
59 imunit);
63 static GnmValue *
64 value_new_complex (gnm_complex const *c, char imunit)
66 if (gnm_complex_invalid_p (c))
67 return value_new_error_NUM (NULL);
68 else if (GNM_CREALP (*c))
69 return value_new_float (c->re);
70 else
71 return value_new_string_nocopy (gnm_complex_to_string (c, imunit));
74 static GnmValue *
75 value_new_complexv (gnm_complex c, char imunit)
77 return value_new_complex (&c, imunit);
81 /***************************************************************************/
83 static GnmFuncHelp const help_complex[] = {
84 { GNM_FUNC_HELP_NAME, F_("COMPLEX:a complex number of the form @{x} + @{y}@{i}") },
85 { GNM_FUNC_HELP_ARG, F_("x:real part") },
86 { GNM_FUNC_HELP_ARG, F_("y:imaginary part") },
87 { GNM_FUNC_HELP_ARG, F_("i:the suffix for the complex number, either \"i\" or \"j\"; defaults to \"i\"") },
88 { GNM_FUNC_HELP_NOTE, F_("If @{i} is neither \"i\" nor \"j\", COMPLEX returns #VALUE!") },
89 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
90 { GNM_FUNC_HELP_EXAMPLES, "=COMPLEX(1,-1)" },
91 { GNM_FUNC_HELP_END}
94 static GnmValue *
95 gnumeric_complex (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
97 gnm_complex c = GNM_CMAKE (value_get_as_float (argv[0]),
98 value_get_as_float (argv[1]));
99 char const *suffix = argv[2] ? value_peek_string (argv[2]) : "i";
101 if (strcmp (suffix, "i") != 0 && strcmp (suffix, "j") != 0)
102 return value_new_error_VALUE (ei->pos);
104 return value_new_complex (&c, *suffix);
107 /***************************************************************************/
109 static GnmFuncHelp const help_imaginary[] = {
110 { GNM_FUNC_HELP_NAME, F_("IMAGINARY:the imaginary part of the complex number @{z}") },
111 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
112 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
113 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
114 { GNM_FUNC_HELP_EXAMPLES, "=IMAGINARY(\"132-j\")" },
115 { GNM_FUNC_HELP_SEEALSO, "IMREAL" },
116 { GNM_FUNC_HELP_END}
119 static GnmValue *
120 gnumeric_imaginary (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
122 gnm_complex c;
123 char imunit;
125 if (VALUE_IS_NUMBER (argv[0]))
126 return value_new_float (0.0);
128 if (value_get_as_complex (argv[0], &c, &imunit))
129 return value_new_error_NUM (ei->pos);
131 return value_new_float (c.im);
134 /***************************************************************************/
136 static GnmFuncHelp const help_imabs[] = {
137 { GNM_FUNC_HELP_NAME, F_("IMABS:the absolute value of the complex number @{z}") },
138 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
139 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
140 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
141 { GNM_FUNC_HELP_EXAMPLES, "=IMABS(\"2-j\")" },
142 { GNM_FUNC_HELP_SEEALSO, "IMAGINARY,IMREAL" },
143 { GNM_FUNC_HELP_END}
146 static GnmValue *
147 gnumeric_imabs (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
149 gnm_complex c;
150 char imunit;
152 if (value_get_as_complex (argv[0], &c, &imunit))
153 return value_new_error_NUM (ei->pos);
155 return value_new_float (GNM_CABS (c));
158 /***************************************************************************/
160 static GnmFuncHelp const help_imreal[] = {
161 { GNM_FUNC_HELP_NAME, F_("IMREAL:the real part of the complex number @{z}") },
162 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
163 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
164 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
165 { GNM_FUNC_HELP_EXAMPLES, "=IMREAL(\"132-j\")" },
166 { GNM_FUNC_HELP_SEEALSO, "IMAGINARY" },
167 { GNM_FUNC_HELP_END}
170 static GnmValue *
171 gnumeric_imreal (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
173 gnm_complex c;
174 char imunit;
176 if (VALUE_IS_NUMBER (argv[0]))
177 return value_dup (argv[0]);
179 if (value_get_as_complex (argv[0], &c, &imunit))
180 return value_new_error_NUM (ei->pos);
182 return value_new_float (c.re);
185 /***************************************************************************/
187 static GnmFuncHelp const help_imconjugate[] = {
188 { GNM_FUNC_HELP_NAME, F_("IMCONJUGATE:the complex conjugate of the complex number @{z}") },
189 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
190 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
191 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
192 { GNM_FUNC_HELP_EXAMPLES, "=IMCONJUGATE(\"1-j\")" },
193 { GNM_FUNC_HELP_SEEALSO, "IMAGINARY,IMREAL" },
194 { GNM_FUNC_HELP_END}
197 static GnmValue *
198 gnumeric_imconjugate (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
200 gnm_complex c;
201 char imunit;
203 if (value_get_as_complex (argv[0], &c, &imunit))
204 return value_new_error_NUM (ei->pos);
206 return value_new_complexv (GNM_CCONJ (c), imunit);
209 /***************************************************************************/
211 static GnmFuncHelp const help_iminv[] = {
212 { GNM_FUNC_HELP_NAME, F_("IMINV:the reciprocal, or inverse, of the complex number @{z}") },
213 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
214 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
215 { GNM_FUNC_HELP_EXAMPLES, "=IMINV(\"1-j\")" },
216 { GNM_FUNC_HELP_END}
219 static GnmValue *
220 gnumeric_iminv (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
222 gnm_complex c;
223 char imunit;
225 if (value_get_as_complex (argv[0], &c, &imunit))
226 return value_new_error_NUM (ei->pos);
228 return value_new_complexv (GNM_CINV (c), imunit);
231 /***************************************************************************/
233 static GnmFuncHelp const help_imneg[] = {
234 { GNM_FUNC_HELP_NAME, F_("IMNEG:the negative of the complex number @{z}") },
235 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
236 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
237 { GNM_FUNC_HELP_EXAMPLES, "=IMNEG(\"1-j\")" },
238 { GNM_FUNC_HELP_END}
241 static GnmValue *
242 gnumeric_imneg (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
244 gnm_complex c;
245 char imunit;
247 if (value_get_as_complex (argv[0], &c, &imunit))
248 return value_new_error_NUM (ei->pos);
250 return value_new_complexv (GNM_CNEG (c), imunit);
253 /***************************************************************************/
255 static GnmFuncHelp const help_imcos[] = {
256 { GNM_FUNC_HELP_NAME, F_("IMCOS:the cosine of the complex number @{z}") },
257 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
258 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
259 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
260 { GNM_FUNC_HELP_EXAMPLES, "=IMCOS(\"1+j\")" },
261 { GNM_FUNC_HELP_SEEALSO, "IMSIN,IMTAN" },
262 { GNM_FUNC_HELP_END}
266 static GnmValue *
267 gnumeric_imcos (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
269 gnm_complex c;
270 char imunit;
272 if (value_get_as_complex (argv[0], &c, &imunit))
273 return value_new_error_NUM (ei->pos);
275 return value_new_complexv (GNM_CCOS (c), imunit);
278 /***************************************************************************/
280 static GnmFuncHelp const help_imtan[] = {
281 { GNM_FUNC_HELP_NAME, F_("IMTAN:the tangent of the complex number @{z}") },
282 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
283 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
284 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
285 { GNM_FUNC_HELP_EXAMPLES, "=IMTAN(\"2-j\")" },
286 { GNM_FUNC_HELP_SEEALSO, "IMSIN,IMCOS" },
287 { GNM_FUNC_HELP_END}
291 static GnmValue *
292 gnumeric_imtan (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
294 gnm_complex c;
295 char imunit;
297 if (value_get_as_complex (argv[0], &c, &imunit))
298 return value_new_error_NUM (ei->pos);
300 return value_new_complexv (GNM_CTAN (c), imunit);
303 /***************************************************************************/
305 static GnmFuncHelp const help_imsec[] = {
306 { GNM_FUNC_HELP_NAME, F_("IMSEC:the secant of the complex number @{z}") },
307 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
308 { GNM_FUNC_HELP_DESCRIPTION, F_("IMSEC(@{z}) = 1/IMCOS(@{z}).") },
309 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
310 { GNM_FUNC_HELP_EXAMPLES, "=IMSEC(\"2-j\")" },
311 { GNM_FUNC_HELP_SEEALSO, "IMCSC,IMCOT" },
312 { GNM_FUNC_HELP_END}
316 static GnmValue *
317 gnumeric_imsec (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
319 gnm_complex c;
320 char imunit;
322 if (value_get_as_complex (argv[0], &c, &imunit))
323 return value_new_error_NUM (ei->pos);
325 return value_new_complexv (GNM_CINV (GNM_CCOS (c)), imunit);
328 /***************************************************************************/
330 static GnmFuncHelp const help_imcsc[] = {
331 { GNM_FUNC_HELP_NAME, F_("IMCSC:the cosecant of the complex number @{z}") },
332 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
333 { GNM_FUNC_HELP_DESCRIPTION, F_("IMCSC(@{z}) = 1/IMSIN(@{z}).") },
334 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
335 { GNM_FUNC_HELP_EXAMPLES, "=IMCSC(\"2-j\")" },
336 { GNM_FUNC_HELP_SEEALSO, "IMSEC,IMCOT" },
337 { GNM_FUNC_HELP_END}
340 static GnmValue *
341 gnumeric_imcsc (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
343 gnm_complex c;
344 char imunit;
346 if (value_get_as_complex (argv[0], &c, &imunit))
347 return value_new_error_NUM (ei->pos);
349 return value_new_complexv (GNM_CINV (GNM_CSIN (c)), imunit);
352 /***************************************************************************/
354 static GnmFuncHelp const help_imcot[] = {
355 { GNM_FUNC_HELP_NAME, F_("IMCOT:the cotangent of the complex number @{z}") },
356 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
357 { GNM_FUNC_HELP_DESCRIPTION, F_("IMCOT(@{z}) = IMCOS(@{z})/IMSIN(@{z}).") },
358 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
359 { GNM_FUNC_HELP_EXAMPLES, "=IMCOT(\"2-i\")" },
360 { GNM_FUNC_HELP_EXAMPLES, "=IMCOT(\"2+j\")" },
361 { GNM_FUNC_HELP_SEEALSO, "IMSEC,IMCSC" },
362 { GNM_FUNC_HELP_END}
365 static GnmValue *
366 gnumeric_imcot (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
368 gnm_complex c;
369 char imunit;
371 if (value_get_as_complex (argv[0], &c, &imunit))
372 return value_new_error_NUM (ei->pos);
374 return value_new_complexv (GNM_CINV (GNM_CTAN (c)), imunit);
377 /***************************************************************************/
379 static GnmFuncHelp const help_imexp[] = {
380 { GNM_FUNC_HELP_NAME, F_("IMEXP:the exponential of the complex number @{z}") },
381 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
382 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
383 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
384 { GNM_FUNC_HELP_EXAMPLES, "=IMEXP(\"2-i\")" },
385 { GNM_FUNC_HELP_EXAMPLES, "=IMEXP(\"2+j\")" },
386 { GNM_FUNC_HELP_SEEALSO, "IMLN" },
387 { GNM_FUNC_HELP_END}
391 static GnmValue *
392 gnumeric_imexp (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
394 gnm_complex c;
395 char imunit;
397 if (value_get_as_complex (argv[0], &c, &imunit))
398 return value_new_error_NUM (ei->pos);
400 return value_new_complexv (GNM_CEXP (c), imunit);
403 /***************************************************************************/
405 static GnmFuncHelp const help_imargument[] = {
406 { GNM_FUNC_HELP_NAME, F_("IMARGUMENT:the argument theta of the complex number @{z} ") },
407 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
408 { GNM_FUNC_HELP_DESCRIPTION, F_("The argument theta of a complex number is its angle in radians from the real axis.") },
409 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
410 { GNM_FUNC_HELP_NOTE, F_("If @{z} is 0, 0 is returned. This is different from Excel which returns an error.") },
411 { GNM_FUNC_HELP_EXAMPLES, "=IMARGUMENT(\"2-j\")" },
412 { GNM_FUNC_HELP_EXAMPLES, "=IMARGUMENT(0)" },
413 { GNM_FUNC_HELP_END}
416 static GnmValue *
417 gnumeric_imargument (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
419 gnm_complex c;
420 char imunit;
422 if (value_get_as_complex (argv[0], &c, &imunit))
423 return value_new_error_NUM (ei->pos);
425 return value_new_float (GNM_CARG (c));
428 /***************************************************************************/
430 static GnmFuncHelp const help_imln[] = {
431 { GNM_FUNC_HELP_NAME, F_("IMLN:the natural logarithm of the complex number @{z}") },
432 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
433 { GNM_FUNC_HELP_DESCRIPTION, F_("The result will have an imaginary part between -\xcf\x80 and +\xcf\x80.\n"
434 "The natural logarithm is not uniquely defined on complex numbers. "
435 "You may need to add or subtract an even multiple of \xcf\x80 to the imaginary part.")},
436 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
437 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
438 { GNM_FUNC_HELP_EXAMPLES, "=IMLN(\"3-j\")" },
439 { GNM_FUNC_HELP_SEEALSO, "IMEXP,IMLOG2,IMLOG10" },
440 { GNM_FUNC_HELP_END}
443 static GnmValue *
444 gnumeric_imln (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
446 gnm_complex c;
447 char imunit;
449 if (value_get_as_complex (argv[0], &c, &imunit))
450 return value_new_error_NUM (ei->pos);
452 return value_new_complexv (GNM_CLN (c), imunit);
455 /***************************************************************************/
457 static GnmFuncHelp const help_imlog2[] = {
458 { GNM_FUNC_HELP_NAME, F_("IMLOG2:the base-2 logarithm of the complex number @{z}") },
459 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
460 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
461 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
462 { GNM_FUNC_HELP_EXAMPLES, "=IMLOG2(\"3-j\")" },
463 { GNM_FUNC_HELP_SEEALSO, "IMLN,IMLOG10" },
464 { GNM_FUNC_HELP_END}
468 static GnmValue *
469 gnumeric_imlog2 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
471 gnm_complex c;
472 char imunit;
474 if (value_get_as_complex (argv[0], &c, &imunit))
475 return value_new_error_NUM (ei->pos);
477 return value_new_complexv (GNM_CSCALE (GNM_CLN (c), 1 / M_LN2gnum), imunit);
480 /***************************************************************************/
482 static GnmFuncHelp const help_imlog10[] = {
483 { GNM_FUNC_HELP_NAME, F_("IMLOG10:the base-10 logarithm of the complex number @{z}") },
484 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
485 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
486 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
487 { GNM_FUNC_HELP_EXAMPLES, "=IMLOG10(\"3-j\")" },
488 { GNM_FUNC_HELP_SEEALSO, "IMLN,IMLOG2" },
489 { GNM_FUNC_HELP_END}
492 static GnmValue *
493 gnumeric_imlog10 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
495 gnm_complex c;
496 char imunit;
498 if (value_get_as_complex (argv[0], &c, &imunit))
499 return value_new_error_NUM (ei->pos);
501 return value_new_complexv (GNM_CSCALE (GNM_CLN (c), M_LN10INVgnum), imunit);
504 /***************************************************************************/
506 static GnmFuncHelp const help_impower[] = {
507 { GNM_FUNC_HELP_NAME, F_("IMPOWER:the complex number @{z1} raised to the @{z2}th power") },
508 { GNM_FUNC_HELP_ARG, F_("z1:a complex number") },
509 { GNM_FUNC_HELP_ARG, F_("z2:a complex number") },
510 { GNM_FUNC_HELP_NOTE, F_("If @{z1} or @{z2} is not a valid complex number, #VALUE! is returned.") },
511 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
512 { GNM_FUNC_HELP_EXAMPLES, "=IMPOWER(\"4-j\",2)" },
513 { GNM_FUNC_HELP_SEEALSO, "IMSQRT" },
514 { GNM_FUNC_HELP_END}
517 static GnmValue *
518 gnumeric_impower (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
520 gnm_complex a, b;
521 char imunit;
523 if (value_get_as_complex (argv[0], &a, &imunit))
524 return value_new_error_NUM (ei->pos);
526 if (value_get_as_complex (argv[1], &b, &imunit))
527 return value_new_error_NUM (ei->pos);
529 if (GNM_CZEROP (a) && GNM_CZEROP (b))
530 return value_new_error_DIV0 (ei->pos);
532 return value_new_complexv (GNM_CPOW (a, b), imunit);
535 /***************************************************************************/
537 static GnmFuncHelp const help_imdiv[] = {
538 { GNM_FUNC_HELP_NAME, F_("IMDIV:the quotient of two complex numbers @{z1}/@{z2}") },
539 { GNM_FUNC_HELP_ARG, F_("z1:a complex number") },
540 { GNM_FUNC_HELP_ARG, F_("z2:a complex number") },
541 { GNM_FUNC_HELP_NOTE, F_("If @{z1} or @{z2} is not a valid complex number, #VALUE! is returned.") },
542 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
543 { GNM_FUNC_HELP_EXAMPLES, "=IMDIV(\"2-j\",\"2+j\")" },
544 { GNM_FUNC_HELP_SEEALSO, "IMPRODUCT" },
545 { GNM_FUNC_HELP_END}
549 static GnmValue *
550 gnumeric_imdiv (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
552 gnm_complex a, b;
553 char imunit;
555 if (value_get_as_complex (argv[0], &a, &imunit))
556 return value_new_error_NUM (ei->pos);
558 if (value_get_as_complex (argv[1], &b, &imunit))
559 return value_new_error_NUM (ei->pos);
561 if (GNM_CZEROP (b))
562 return value_new_error_DIV0 (ei->pos);
564 return value_new_complexv (GNM_CDIV (a, b), imunit);
567 /***************************************************************************/
569 static GnmFuncHelp const help_imsin[] = {
570 { GNM_FUNC_HELP_NAME, F_("IMSIN:the sine of the complex number @{z}") },
571 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
572 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
573 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
574 { GNM_FUNC_HELP_EXAMPLES, "=IMSIN(\"1+j\")" },
575 { GNM_FUNC_HELP_SEEALSO, "IMCOS,IMTAN" },
576 { GNM_FUNC_HELP_END}
579 static GnmValue *
580 gnumeric_imsin (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
582 gnm_complex c;
583 char imunit;
585 if (value_get_as_complex (argv[0], &c, &imunit))
586 return value_new_error_NUM (ei->pos);
588 return value_new_complexv (GNM_CSIN (c), imunit);
591 /***************************************************************************/
593 static GnmFuncHelp const help_imsinh[] = {
594 { GNM_FUNC_HELP_NAME, F_("IMSINH:the hyperbolic sine of the complex number @{z}") },
595 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
596 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
597 { GNM_FUNC_HELP_EXAMPLES, "=IMSINH(\"1+j\")" },
598 { GNM_FUNC_HELP_SEEALSO, "IMCOSH,IMTANH" },
599 { GNM_FUNC_HELP_END}
602 static GnmValue *
603 gnumeric_imsinh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
605 gnm_complex c;
606 char imunit;
608 if (value_get_as_complex (argv[0], &c, &imunit))
609 return value_new_error_NUM (ei->pos);
611 return value_new_complexv (GNM_CSINH (c), imunit);
614 /***************************************************************************/
616 static GnmFuncHelp const help_imcosh[] = {
617 { GNM_FUNC_HELP_NAME, F_("IMCOSH:the hyperbolic cosine of the complex number @{z}") },
618 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
619 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
620 { GNM_FUNC_HELP_EXAMPLES, "=IMCOSH(\"1+j\")" },
621 { GNM_FUNC_HELP_SEEALSO, "IMSINH,IMTANH" },
622 { GNM_FUNC_HELP_END}
626 static GnmValue *
627 gnumeric_imcosh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
629 gnm_complex c;
630 char imunit;
632 if (value_get_as_complex (argv[0], &c, &imunit))
633 return value_new_error_NUM (ei->pos);
635 return value_new_complexv (GNM_CCOSH (c), imunit);
638 /***************************************************************************/
640 static GnmFuncHelp const help_imtanh[] = {
641 { GNM_FUNC_HELP_NAME, F_("IMTANH:the hyperbolic tangent of the complex number @{z}") },
642 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
643 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
644 { GNM_FUNC_HELP_EXAMPLES, "=IMTANH(\"1+j\")" },
645 { GNM_FUNC_HELP_SEEALSO, "IMSINH,IMCOSH" },
646 { GNM_FUNC_HELP_END}
650 static GnmValue *
651 gnumeric_imtanh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
653 gnm_complex c;
654 char imunit;
656 if (value_get_as_complex (argv[0], &c, &imunit))
657 return value_new_error_NUM (ei->pos);
659 return value_new_complexv (GNM_CTANH (c), imunit);
662 /***************************************************************************/
664 static GnmFuncHelp const help_imsech[] = {
665 { GNM_FUNC_HELP_NAME, F_("IMSECH:the hyperbolic secant of the complex number @{z}") },
666 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
667 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
668 { GNM_FUNC_HELP_EXAMPLES, "=IMSECH(\"1+j\")" },
669 { GNM_FUNC_HELP_SEEALSO, "IMCSCH,IMCOTH" },
670 { GNM_FUNC_HELP_END}
673 static GnmValue *
674 gnumeric_imsech (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
676 gnm_complex c;
677 char imunit;
679 if (value_get_as_complex (argv[0], &c, &imunit))
680 return value_new_error_NUM (ei->pos);
682 return value_new_complexv (GNM_CSECH (c), imunit);
685 /***************************************************************************/
687 static GnmFuncHelp const help_imcsch[] = {
688 { GNM_FUNC_HELP_NAME, F_("IMCSCH:the hyperbolic cosecant of the complex number @{z}") },
689 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
690 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
691 { GNM_FUNC_HELP_EXAMPLES, "=IMCSCH(\"1+j\")" },
692 { GNM_FUNC_HELP_SEEALSO, "IMSECH,IMCOTH" },
693 { GNM_FUNC_HELP_END}
697 static GnmValue *
698 gnumeric_imcsch (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
700 gnm_complex c;
701 char imunit;
703 if (value_get_as_complex (argv[0], &c, &imunit))
704 return value_new_error_NUM (ei->pos);
706 return value_new_complexv (GNM_CCSCH (c), imunit);
709 /***************************************************************************/
711 static GnmFuncHelp const help_imcoth[] = {
712 { GNM_FUNC_HELP_NAME, F_("IMCOTH:the hyperbolic cotangent of the complex number @{z}") },
713 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
714 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
715 { GNM_FUNC_HELP_EXAMPLES, "=IMCOTH(\"1+j\")" },
716 { GNM_FUNC_HELP_SEEALSO, "IMSECH,IMCSCH" },
717 { GNM_FUNC_HELP_END}
720 static GnmValue *
721 gnumeric_imcoth (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
723 gnm_complex c;
724 char imunit;
726 if (value_get_as_complex (argv[0], &c, &imunit))
727 return value_new_error_NUM (ei->pos);
729 return value_new_complexv (GNM_CCOTH (c), imunit);
732 /***************************************************************************/
734 static GnmFuncHelp const help_imarcsin[] = {
735 { GNM_FUNC_HELP_NAME, F_("IMARCSIN:the complex arcsine of the complex number @{z}") },
736 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
737 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCSIN returns the complex arcsine of the complex number "
738 "@{z}. The branch cuts are on the real axis, less than -1 and greater than 1.") },
739 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
740 { GNM_FUNC_HELP_EXAMPLES, "=IMARCSIN(\"1+j\")" },
741 { GNM_FUNC_HELP_SEEALSO, "IMARCCOS,IMARCTAN" },
742 { GNM_FUNC_HELP_END}
746 static GnmValue *
747 gnumeric_imarcsin (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
749 gnm_complex c;
750 char imunit;
752 if (value_get_as_complex (argv[0], &c, &imunit))
753 return value_new_error_NUM (ei->pos);
755 return value_new_complexv (GNM_CARCSIN (c), imunit);
758 /***************************************************************************/
760 static GnmFuncHelp const help_imarccos[] = {
761 { GNM_FUNC_HELP_NAME, F_("IMARCCOS:the complex arccosine of the complex number ") },
762 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
763 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCCOS returns the complex arccosine of the complex number "
764 "@{z}. The branch cuts are on the real axis, less than -1 and greater than 1.") },
765 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
766 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCOS(\"1+j\")" },
767 { GNM_FUNC_HELP_SEEALSO, "IMARCSIN,IMARCTAN" },
768 { GNM_FUNC_HELP_END}
772 static GnmValue *
773 gnumeric_imarccos (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
775 gnm_complex c;
776 char imunit;
778 if (value_get_as_complex (argv[0], &c, &imunit))
779 return value_new_error_NUM (ei->pos);
781 return value_new_complexv (GNM_CARCCOS (c), imunit);
784 /***************************************************************************/
786 static GnmFuncHelp const help_imarctan[] = {
787 { GNM_FUNC_HELP_NAME, F_("IMARCTAN:the complex arctangent of the complex number ") },
788 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
789 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCTAN returns the complex arctangent of the complex number "
790 "@{z}. The branch cuts are on the imaginary axis, below -i and above i.") },
791 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
792 { GNM_FUNC_HELP_EXAMPLES, "=IMARCTAN(\"1+j\")" },
793 { GNM_FUNC_HELP_SEEALSO, "IMARCSIN,IMARCCOS" },
794 { GNM_FUNC_HELP_END}
798 static GnmValue *
799 gnumeric_imarctan (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
801 gnm_complex c;
802 char imunit;
804 if (value_get_as_complex (argv[0], &c, &imunit))
805 return value_new_error_NUM (ei->pos);
807 return value_new_complexv (GNM_CARCTAN (c), imunit);
810 /***************************************************************************/
812 static GnmFuncHelp const help_imarcsec[] = {
813 { GNM_FUNC_HELP_NAME, F_("IMARCSEC:the complex arcsecant of the complex number @{z}") },
814 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
815 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
816 { GNM_FUNC_HELP_EXAMPLES, "=IMARCSEC(\"1+j\")" },
817 { GNM_FUNC_HELP_SEEALSO, "IMARCCSC,IMARCCOT" },
818 { GNM_FUNC_HELP_END}
821 static GnmValue *
822 gnumeric_imarcsec (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
824 gnm_complex c;
825 char imunit;
827 if (value_get_as_complex (argv[0], &c, &imunit))
828 return value_new_error_NUM (ei->pos);
830 return value_new_complexv (GNM_CARCSEC (c), imunit);
833 /***************************************************************************/
835 static GnmFuncHelp const help_imarccsc[] = {
836 { GNM_FUNC_HELP_NAME, F_("IMARCCSC:the complex arccosecant of the complex number @{z}") },
837 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
838 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
839 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCSC(\"1+j\")" },
840 { GNM_FUNC_HELP_SEEALSO, "IMARCSEC,IMARCCOT" },
841 { GNM_FUNC_HELP_END}
845 static GnmValue *
846 gnumeric_imarccsc (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
848 gnm_complex c;
849 char imunit;
851 if (value_get_as_complex (argv[0], &c, &imunit))
852 return value_new_error_NUM (ei->pos);
854 return value_new_complexv (GNM_CARCCSC (c), imunit);
857 /***************************************************************************/
859 static GnmFuncHelp const help_imarccot[] = {
860 { GNM_FUNC_HELP_NAME, F_("IMARCCOT:the complex arccotangent of the complex number @{z}") },
861 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
862 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
863 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCOT(\"1+j\")" },
864 { GNM_FUNC_HELP_SEEALSO, "IMARCSEC,IMARCCSC" },
865 { GNM_FUNC_HELP_END}
868 static GnmValue *
869 gnumeric_imarccot (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
871 gnm_complex c;
872 char imunit;
874 if (value_get_as_complex (argv[0], &c, &imunit))
875 return value_new_error_NUM (ei->pos);
877 return value_new_complexv (GNM_CARCCOT (c), imunit);
880 /***************************************************************************/
882 static GnmFuncHelp const help_imarcsinh[] = {
883 { GNM_FUNC_HELP_NAME, F_("IMARCSINH:the complex hyperbolic arcsine of the complex number @{z}") },
884 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
885 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCSINH returns the complex hyperbolic arcsine of the complex number @{z}. "
886 " The branch cuts are on the imaginary axis, below -i and above i.") },
887 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
888 { GNM_FUNC_HELP_EXAMPLES, "=IMARCSINH(\"1+j\")" },
889 { GNM_FUNC_HELP_SEEALSO, "IMARCCOSH,IMARCTANH" },
890 { GNM_FUNC_HELP_END}
894 static GnmValue *
895 gnumeric_imarcsinh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
897 gnm_complex c;
898 char imunit;
900 if (value_get_as_complex (argv[0], &c, &imunit))
901 return value_new_error_NUM (ei->pos);
903 return value_new_complexv (GNM_CARCSINH (c), imunit);
906 /***************************************************************************/
908 static GnmFuncHelp const help_imarccosh[] = {
909 { GNM_FUNC_HELP_NAME, F_("IMARCCOSH:the complex hyperbolic arccosine of the complex number @{z}") },
910 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
911 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCCOSH returns the complex hyperbolic arccosine of the "
912 "complex number @{z}. The branch cut is on the real "
913 "axis, less than 1.") },
914 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
915 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCOSH(\"1+j\")" },
916 { GNM_FUNC_HELP_SEEALSO, "IMARCSINH,IMARCTANH" },
917 { GNM_FUNC_HELP_END}
921 static GnmValue *
922 gnumeric_imarccosh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
924 gnm_complex c;
925 char imunit;
927 if (value_get_as_complex (argv[0], &c, &imunit))
928 return value_new_error_NUM (ei->pos);
930 return value_new_complexv (GNM_CARCCOSH (c), imunit);
933 /***************************************************************************/
935 static GnmFuncHelp const help_imarctanh[] = {
936 { GNM_FUNC_HELP_NAME, F_("IMARCTANH:the complex hyperbolic arctangent of the complex number @{z}") },
937 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
938 { GNM_FUNC_HELP_DESCRIPTION, F_("IMARCTANH returns the complex hyperbolic arctangent of the "
939 "complex number @{z}. The branch cuts are on the "
940 "real axis, less than -1 and greater than 1.") },
941 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
942 { GNM_FUNC_HELP_EXAMPLES, "=IMARCTANH(\"1+j\")" },
943 { GNM_FUNC_HELP_SEEALSO, "IMARCSINH,IMARCCOSH" },
944 { GNM_FUNC_HELP_END}
948 static GnmValue *
949 gnumeric_imarctanh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
951 gnm_complex c;
952 char imunit;
954 if (value_get_as_complex (argv[0], &c, &imunit))
955 return value_new_error_NUM (ei->pos);
957 return value_new_complexv (GNM_CARCTANH (c), imunit);
960 /***************************************************************************/
962 static GnmFuncHelp const help_imarcsech[] = {
963 { GNM_FUNC_HELP_NAME, F_("IMARCSECH:the complex hyperbolic arcsecant of the complex number @{z}") },
964 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
965 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
966 { GNM_FUNC_HELP_EXAMPLES, "=IMARCSECH(\"1+j\")" },
967 { GNM_FUNC_HELP_SEEALSO, "IMARCCSCH,IMARCCOTH" },
968 { GNM_FUNC_HELP_END}
971 static GnmValue *
972 gnumeric_imarcsech (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
974 gnm_complex c;
975 char imunit;
977 if (value_get_as_complex (argv[0], &c, &imunit))
978 return value_new_error_NUM (ei->pos);
980 return value_new_complexv (GNM_CARCSECH (c), imunit);
983 /***************************************************************************/
985 static GnmFuncHelp const help_imarccsch[] = {
986 { GNM_FUNC_HELP_NAME, F_("IMARCCSCH:the complex hyperbolic arccosecant of the complex number @{z}") },
987 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
988 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
989 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCSCH(\"1+j\")" },
990 { GNM_FUNC_HELP_SEEALSO, "IMARCSECH,IMARCCOTH" },
991 { GNM_FUNC_HELP_END}
995 static GnmValue *
996 gnumeric_imarccsch (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
998 gnm_complex c;
999 char imunit;
1001 if (value_get_as_complex (argv[0], &c, &imunit))
1002 return value_new_error_NUM (ei->pos);
1004 return value_new_complexv (GNM_CARCCSCH (c), imunit);
1007 /***************************************************************************/
1009 static GnmFuncHelp const help_imarccoth[] = {
1010 { GNM_FUNC_HELP_NAME, F_("IMARCCOTH:the complex hyperbolic arccotangent of the complex number @{z}") },
1011 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
1012 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
1013 { GNM_FUNC_HELP_EXAMPLES, "=IMARCCOTH(\"1+j\")" },
1014 { GNM_FUNC_HELP_SEEALSO, "IMARCSECH,IMARCCSCH" },
1015 { GNM_FUNC_HELP_END}
1019 static GnmValue *
1020 gnumeric_imarccoth (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1022 gnm_complex c;
1023 char imunit;
1025 if (value_get_as_complex (argv[0], &c, &imunit))
1026 return value_new_error_NUM (ei->pos);
1028 return value_new_complexv (GNM_CARCCOTH (c), imunit);
1031 /***************************************************************************/
1033 static GnmFuncHelp const help_imsqrt[] = {
1034 { GNM_FUNC_HELP_NAME, F_("IMSQRT:the square root of the complex number @{z}") },
1035 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
1036 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
1037 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
1038 { GNM_FUNC_HELP_EXAMPLES, "=IMSQRT(\"1+j\")" },
1039 { GNM_FUNC_HELP_SEEALSO, "IMPOWER" },
1040 { GNM_FUNC_HELP_END}
1044 static GnmValue *
1045 gnumeric_imsqrt (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1047 gnm_complex c;
1048 char imunit;
1050 if (value_get_as_complex (argv[0], &c, &imunit))
1051 return value_new_error_NUM (ei->pos);
1053 return value_new_complexv (GNM_CSQRT (c), imunit);
1056 /***************************************************************************/
1058 static GnmFuncHelp const help_imfact[] = {
1059 { GNM_FUNC_HELP_NAME, F_("IMFACT:the factorial of the complex number @{z}") },
1060 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
1061 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
1062 { GNM_FUNC_HELP_EXAMPLES, "=IMFACT(\"1+j\")" },
1063 { GNM_FUNC_HELP_SEEALSO, "IMGAMMA" },
1064 { GNM_FUNC_HELP_END}
1068 static GnmValue *
1069 gnumeric_imfact (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1071 gnm_complex c;
1072 char imunit;
1074 if (value_get_as_complex (argv[0], &c, &imunit))
1075 return value_new_error_NUM (ei->pos);
1077 return value_new_complexv (gnm_complex_fact (c, NULL), imunit);
1080 /***************************************************************************/
1082 static GnmFuncHelp const help_imgamma[] = {
1083 { GNM_FUNC_HELP_NAME, F_("IMGAMMA:the gamma function of the complex number @{z}") },
1084 { GNM_FUNC_HELP_ARG, F_("z:a complex number") },
1085 { GNM_FUNC_HELP_NOTE, F_("If @{z} is not a valid complex number, #VALUE! is returned.") },
1086 { GNM_FUNC_HELP_EXAMPLES, "=IMGAMMA(\"1+j\")" },
1087 { GNM_FUNC_HELP_SEEALSO, "IMGAMMA" },
1088 { GNM_FUNC_HELP_END}
1092 static GnmValue *
1093 gnumeric_imgamma (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1095 gnm_complex c;
1096 char imunit;
1098 if (value_get_as_complex (argv[0], &c, &imunit))
1099 return value_new_error_NUM (ei->pos);
1101 return value_new_complexv (gnm_complex_gamma (c, NULL), imunit);
1104 /***************************************************************************/
1106 static GnmFuncHelp const help_imigamma[] = {
1107 { GNM_FUNC_HELP_NAME, F_("IMIGAMMA:the incomplete Gamma function")},
1108 { GNM_FUNC_HELP_ARG, F_("a:a complex number")},
1109 { GNM_FUNC_HELP_ARG, F_("z:a complex number")},
1110 { GNM_FUNC_HELP_ARG, F_("lower:if true (the default), the lower incomplete gamma function, otherwise the upper incomplete gamma function")},
1111 { GNM_FUNC_HELP_ARG, F_("regularize:if true (the default), the regularized version of the incomplete gamma function")},
1112 { GNM_FUNC_HELP_NOTE, F_("The regularized incomplete gamma function is the unregularized incomplete gamma function divided by GAMMA(@{a}).") },
1113 { GNM_FUNC_HELP_EXAMPLES, "=IMIGAMMA(2.5,-1.8,TRUE,TRUE)" },
1114 { GNM_FUNC_HELP_EXAMPLES, "=IMIGAMMA(2.5,-1.8,TRUE,TRUE)" },
1115 { GNM_FUNC_HELP_SEEALSO, "GAMMA,IMIGAMMA"},
1116 { GNM_FUNC_HELP_END}
1120 static GnmValue *
1121 gnumeric_imigamma (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1123 gnm_complex a, z;
1124 char imunit;
1125 gboolean lower = argv[2] ? value_get_as_checked_bool (argv[2]) : TRUE;
1126 gboolean reg = argv[3] ? value_get_as_checked_bool (argv[3]) : TRUE;
1128 if (value_get_as_complex (argv[0], &a, &imunit))
1129 return value_new_error_NUM (ei->pos);
1130 if (value_get_as_complex (argv[1], &z, &imunit))
1131 return value_new_error_NUM (ei->pos);
1133 return value_new_complexv (gnm_complex_igamma (a, z, lower, reg), imunit);
1136 /***************************************************************************/
1138 static GnmFuncHelp const help_imsub[] = {
1139 { GNM_FUNC_HELP_NAME, F_("IMSUB:the difference of two complex numbers") },
1140 { GNM_FUNC_HELP_ARG, F_("z1:a complex number") },
1141 { GNM_FUNC_HELP_ARG, F_("z2:a complex number") },
1142 { GNM_FUNC_HELP_NOTE, F_("If @{z1} or @{z2} is not a valid complex number, #VALUE! is returned.") },
1143 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
1144 { GNM_FUNC_HELP_EXAMPLES, "=IMSUB(\"3-j\",\"2+j\")" },
1145 { GNM_FUNC_HELP_SEEALSO, "IMSUM" },
1146 { GNM_FUNC_HELP_END}
1150 static GnmValue *
1151 gnumeric_imsub (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1153 gnm_complex a, b;
1154 char imunit;
1156 if (value_get_as_complex (argv[0], &a, &imunit))
1157 return value_new_error_NUM (ei->pos);
1159 if (value_get_as_complex (argv[1], &b, &imunit))
1160 return value_new_error_NUM (ei->pos);
1162 return value_new_complexv (GNM_CSUB (a, b), imunit);
1165 /***************************************************************************/
1167 static GnmFuncHelp const help_improduct[] = {
1168 { GNM_FUNC_HELP_NAME, F_("IMPRODUCT:the product of the given complex numbers") },
1169 { GNM_FUNC_HELP_ARG, F_("z1:a complex number") },
1170 { GNM_FUNC_HELP_ARG, F_("z2:a complex number") },
1171 { GNM_FUNC_HELP_NOTE, F_("If any of @{z1}, @{z2},... is not a valid complex number, #VALUE! is returned.") },
1172 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
1173 { GNM_FUNC_HELP_EXAMPLES, "=IMPRODUCT(\"2-j\",\"4-2j\")" },
1174 { GNM_FUNC_HELP_SEEALSO, "IMDIV" },
1175 { GNM_FUNC_HELP_END}
1179 typedef enum {
1180 Improduct, Imsum
1181 } eng_imoper_type_t;
1183 typedef struct {
1184 gnm_complex res;
1185 char imunit;
1186 eng_imoper_type_t type;
1187 } eng_imoper_t;
1189 static GnmValue *
1190 callback_function_imoper (GnmEvalPos const *ep, GnmValue const *value, void *closure)
1192 eng_imoper_t *result = closure;
1193 gnm_complex c;
1194 char *imptr, dummy;
1196 imptr = VALUE_IS_NUMBER (value) ? &dummy : &result->imunit;
1197 if (value_get_as_complex (value, &c, imptr))
1198 return value_new_error_NUM (ep);
1200 switch (result->type) {
1201 case Improduct:
1202 result->res = GNM_CMUL (result->res, c);
1203 break;
1204 case Imsum:
1205 result->res = GNM_CADD (result->res, c);
1206 break;
1207 default:
1208 abort ();
1211 return NULL;
1214 static GnmValue *
1215 gnumeric_improduct (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
1217 GnmValue *v;
1218 eng_imoper_t p;
1220 p.type = Improduct;
1221 p.imunit = 'j';
1222 p.res = GNM_C1;
1224 v = function_iterate_argument_values
1225 (ei->pos, callback_function_imoper, &p,
1226 argc, argv, TRUE, CELL_ITER_IGNORE_BLANK);
1228 if (v != NULL)
1229 return v;
1231 return value_new_complexv (p.res, p.imunit);
1234 /***************************************************************************/
1236 static GnmFuncHelp const help_imsum[] = {
1237 { GNM_FUNC_HELP_NAME, F_("IMSUM:the sum of the given complex numbers") },
1238 { GNM_FUNC_HELP_ARG, F_("z1:a complex number") },
1239 { GNM_FUNC_HELP_ARG, F_("z2:a complex number") },
1240 { GNM_FUNC_HELP_NOTE, F_("If any of @{z1}, @{z2},... is not a valid complex number, #VALUE! is returned.") },
1241 { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
1242 { GNM_FUNC_HELP_EXAMPLES, "=IMSUM(\"2-4j\",\"9-j\")" },
1243 { GNM_FUNC_HELP_SEEALSO, "IMSUB" },
1244 { GNM_FUNC_HELP_END}
1248 static GnmValue *
1249 gnumeric_imsum (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
1251 GnmValue *v;
1252 eng_imoper_t p;
1254 p.type = Imsum;
1255 p.imunit = 'j';
1256 p.res = GNM_C0;
1258 v = function_iterate_argument_values
1259 (ei->pos, callback_function_imoper, &p,
1260 argc, argv, TRUE, CELL_ITER_IGNORE_BLANK);
1262 if (v != NULL)
1263 return v;
1265 return value_new_complexv (p.res, p.imunit);
1268 /***************************************************************************/
1270 GnmFuncDescriptor const complex_functions[] = {
1271 { "complex", "ff|s", help_complex,
1272 gnumeric_complex, NULL, NULL, NULL,
1273 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1274 { "imabs", "S", help_imabs,
1275 gnumeric_imabs, NULL, NULL, NULL,
1276 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1277 { "imaginary", "S", help_imaginary,
1278 gnumeric_imaginary, NULL, NULL, NULL,
1279 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1280 { "imargument", "S", help_imargument,
1281 gnumeric_imargument, NULL, NULL, NULL,
1282 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1283 { "imconjugate", "S", help_imconjugate,
1284 gnumeric_imconjugate, NULL, NULL, NULL,
1285 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1286 { "imcos", "S", help_imcos,
1287 gnumeric_imcos, NULL, NULL, NULL,
1288 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1289 { "imdiv", "SS", help_imdiv,
1290 gnumeric_imdiv, NULL, NULL, NULL,
1291 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1292 { "imexp", "S", help_imexp,
1293 gnumeric_imexp, NULL, NULL, NULL,
1294 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1295 { "imln", "S", help_imln,
1296 gnumeric_imln, NULL, NULL, NULL,
1297 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1298 { "imlog10", "S", help_imlog10,
1299 gnumeric_imlog10, NULL, NULL, NULL,
1300 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1301 { "imlog2", "S", help_imlog2,
1302 gnumeric_imlog2, NULL, NULL, NULL,
1303 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1304 { "impower", "SS", help_impower,
1305 gnumeric_impower, NULL, NULL, NULL,
1306 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1307 { "imreal", "S", help_imreal,
1308 gnumeric_imreal, NULL, NULL, NULL,
1309 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1310 { "imsin", "S", help_imsin,
1311 gnumeric_imsin, NULL, NULL, NULL,
1312 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1313 { "imsqrt", "S", help_imsqrt,
1314 gnumeric_imsqrt, NULL, NULL, NULL,
1315 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1316 { "imsub", "SS", help_imsub,
1317 gnumeric_imsub, NULL, NULL, NULL,
1318 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1319 { "imsum", NULL, help_imsum,
1320 NULL, gnumeric_imsum, NULL, NULL,
1321 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1323 { "iminv", "S", help_iminv,
1324 gnumeric_iminv, NULL, NULL, NULL,
1325 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
1326 { "imneg", "S", help_imneg,
1327 gnumeric_imneg, NULL, NULL, NULL,
1328 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1329 { "imtan", "S", help_imtan,
1330 gnumeric_imtan, NULL, NULL, NULL,
1331 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1332 { "improduct", NULL, help_improduct,
1333 NULL, gnumeric_improduct, NULL, NULL,
1334 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
1335 { "imsec", "S", help_imsec,
1336 gnumeric_imsec, NULL, NULL, NULL,
1337 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1338 { "imcsc", "S", help_imcsc,
1339 gnumeric_imcsc, NULL, NULL, NULL,
1340 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1341 { "imcot", "S", help_imcot,
1342 gnumeric_imcot, NULL, NULL, NULL,
1343 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1344 { "imsinh", "S", help_imsinh,
1345 gnumeric_imsinh, NULL, NULL, NULL,
1346 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1347 { "imcosh", "S", help_imcosh,
1348 gnumeric_imcosh, NULL, NULL, NULL,
1349 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1350 { "imtanh", "S", help_imtanh,
1351 gnumeric_imtanh, NULL, NULL, NULL,
1352 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1353 { "imsech", "S", help_imsech,
1354 gnumeric_imsech, NULL, NULL, NULL,
1355 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1356 { "imcsch", "S", help_imcsch,
1357 gnumeric_imcsch, NULL, NULL, NULL,
1358 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1359 { "imcoth", "S", help_imcoth,
1360 gnumeric_imcoth, NULL, NULL, NULL,
1361 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1362 { "imarcsin", "S", help_imarcsin,
1363 gnumeric_imarcsin, NULL, NULL, NULL,
1364 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1365 { "imarccos", "S", help_imarccos,
1366 gnumeric_imarccos, NULL, NULL, NULL,
1367 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1368 { "imarctan", "S", help_imarctan,
1369 gnumeric_imarctan, NULL, NULL, NULL,
1370 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1371 { "imarcsec", "S", help_imarcsec,
1372 gnumeric_imarcsec, NULL, NULL, NULL,
1373 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1374 { "imarccsc", "S", help_imarccsc,
1375 gnumeric_imarccsc, NULL, NULL, NULL,
1376 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1377 { "imarccot", "S", help_imarccot,
1378 gnumeric_imarccot, NULL, NULL, NULL,
1379 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1380 { "imarcsinh", "S", help_imarcsinh,
1381 gnumeric_imarcsinh, NULL, NULL, NULL,
1382 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1383 { "imarccosh", "S", help_imarccosh,
1384 gnumeric_imarccosh, NULL, NULL, NULL,
1385 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1386 { "imarctanh", "S", help_imarctanh,
1387 gnumeric_imarctanh, NULL, NULL, NULL,
1388 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1389 { "imarcsech", "S", help_imarcsech,
1390 gnumeric_imarcsech, NULL, NULL, NULL,
1391 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1392 { "imarccsch", "S", help_imarccsch,
1393 gnumeric_imarccsch, NULL, NULL, NULL,
1394 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1395 { "imarccoth", "S", help_imarccoth,
1396 gnumeric_imarccoth, NULL, NULL, NULL,
1397 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1399 { "imfact", "S", help_imfact,
1400 gnumeric_imfact, NULL, NULL, NULL,
1401 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1402 { "imgamma", "S", help_imgamma,
1403 gnumeric_imgamma, NULL, NULL, NULL,
1404 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
1405 { "imigamma", "SS|bb", help_imigamma,
1406 gnumeric_imigamma, NULL, NULL, NULL,
1407 GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
1409 {NULL}