GnmFunc: make this a GObject.
[gnumeric.git] / plugins / fn-complex / functions.c
blob2a7fcef387f01f3db8934b02adda3f49dbbc5bb7
1 /*
2 * fn-complex.c: Built in complex number functions and functions registration
4 * Authors:
5 * Michael Meeks <michael@ximian.com>
6 * Jukka-Pekka Iivonen (iivonen@iki.fi)
7 * Morten Welinder (terra@gnome.org)
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.
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.
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/>.
23 #include <gnumeric-config.h>
24 #include <gnumeric.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <func.h>
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>
38 #include <goffice/goffice.h>
39 #include <gnm-plugin.h>
40 #include "gsl-complex.h"
43 GNM_PLUGIN_MODULE_HEADER;
45 /* Converts a complex number string into its coefficients. Returns 0 if ok,
46 * 1 if an error occurred.
48 static int
49 value_get_as_complex (GnmValue const *val, gnm_complex *res, char *imunit)
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);
62 static GnmValue *
63 value_new_complex (gnm_complex const *c, char imunit)
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));
73 static GnmValue *
74 value_new_complexv (gnm_complex c, char imunit)
76 return value_new_complex (&c, imunit);
80 /***************************************************************************/
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}
93 static GnmValue *
94 gnumeric_complex (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
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";
100 if (strcmp (suffix, "i") != 0 && strcmp (suffix, "j") != 0)
101 return value_new_error_VALUE (ei->pos);
103 return value_new_complex (&c, *suffix);
106 /***************************************************************************/
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}
118 static GnmValue *
119 gnumeric_imaginary (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
121 gnm_complex c;
122 char imunit;
124 if (VALUE_IS_NUMBER (argv[0]))
125 return value_new_float (0.0);
127 if (value_get_as_complex (argv[0], &c, &imunit))
128 return value_new_error_NUM (ei->pos);
130 return value_new_float (c.im);
133 /***************************************************************************/
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}
145 static GnmValue *
146 gnumeric_imabs (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
148 gnm_complex c;
149 char imunit;
151 if (value_get_as_complex (argv[0], &c, &imunit))
152 return value_new_error_NUM (ei->pos);
154 return value_new_float (GNM_CABS (c));
157 /***************************************************************************/
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}
169 static GnmValue *
170 gnumeric_imreal (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
172 gnm_complex c;
173 char imunit;
175 if (VALUE_IS_NUMBER (argv[0]))
176 return value_dup (argv[0]);
178 if (value_get_as_complex (argv[0], &c, &imunit))
179 return value_new_error_NUM (ei->pos);
181 return value_new_float (c.re);
184 /***************************************************************************/
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}
196 static GnmValue *
197 gnumeric_imconjugate (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
199 gnm_complex c;
200 char imunit;
202 if (value_get_as_complex (argv[0], &c, &imunit))
203 return value_new_error_NUM (ei->pos);
205 return value_new_complexv (GNM_CCONJ (c), imunit);
208 /***************************************************************************/
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}
218 static GnmValue *
219 gnumeric_iminv (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
221 gnm_complex c;
222 char imunit;
224 if (value_get_as_complex (argv[0], &c, &imunit))
225 return value_new_error_NUM (ei->pos);
227 return value_new_complexv (GNM_CINV (c), imunit);
230 /***************************************************************************/
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}
240 static GnmValue *
241 gnumeric_imneg (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
243 gnm_complex c;
244 char imunit;
246 if (value_get_as_complex (argv[0], &c, &imunit))
247 return value_new_error_NUM (ei->pos);
249 return value_new_complexv (GNM_CNEG (c), imunit);
252 /***************************************************************************/
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}
265 static GnmValue *
266 gnumeric_imcos (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
268 gnm_complex c;
269 char imunit;
271 if (value_get_as_complex (argv[0], &c, &imunit))
272 return value_new_error_NUM (ei->pos);
274 return value_new_complexv (GNM_CCOS (c), imunit);
277 /***************************************************************************/
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}
290 static GnmValue *
291 gnumeric_imtan (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
293 gnm_complex c;
294 char imunit;
296 if (value_get_as_complex (argv[0], &c, &imunit))
297 return value_new_error_NUM (ei->pos);
299 return value_new_complexv (GNM_CTAN (c), imunit);
302 /***************************************************************************/
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}
315 static GnmValue *
316 gnumeric_imsec (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
318 gnm_complex c;
319 char imunit;
321 if (value_get_as_complex (argv[0], &c, &imunit))
322 return value_new_error_NUM (ei->pos);
324 return value_new_complexv (GNM_CINV (GNM_CCOS (c)), imunit);
327 /***************************************************************************/
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}
339 static GnmValue *
340 gnumeric_imcsc (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
342 gnm_complex c;
343 char imunit;
345 if (value_get_as_complex (argv[0], &c, &imunit))
346 return value_new_error_NUM (ei->pos);
348 return value_new_complexv (GNM_CINV (GNM_CSIN (c)), imunit);
351 /***************************************************************************/
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}
364 static GnmValue *
365 gnumeric_imcot (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
367 gnm_complex c;
368 char imunit;
370 if (value_get_as_complex (argv[0], &c, &imunit))
371 return value_new_error_NUM (ei->pos);
373 return value_new_complexv (GNM_CINV (GNM_CTAN (c)), imunit);
376 /***************************************************************************/
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}
390 static GnmValue *
391 gnumeric_imexp (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
393 gnm_complex c;
394 char imunit;
396 if (value_get_as_complex (argv[0], &c, &imunit))
397 return value_new_error_NUM (ei->pos);
399 return value_new_complexv (GNM_CEXP (c), imunit);
402 /***************************************************************************/
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}
415 static GnmValue *
416 gnumeric_imargument (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
418 gnm_complex c;
419 char imunit;
421 if (value_get_as_complex (argv[0], &c, &imunit))
422 return value_new_error_NUM (ei->pos);
424 return value_new_float (GNM_CARG (c));
427 /***************************************************************************/
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}
442 static GnmValue *
443 gnumeric_imln (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
445 gnm_complex c;
446 char imunit;
448 if (value_get_as_complex (argv[0], &c, &imunit))
449 return value_new_error_NUM (ei->pos);
451 return value_new_complexv (GNM_CLN (c), imunit);
454 /***************************************************************************/
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}
467 static GnmValue *
468 gnumeric_imlog2 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
470 gnm_complex c;
471 char imunit;
473 if (value_get_as_complex (argv[0], &c, &imunit))
474 return value_new_error_NUM (ei->pos);
476 return value_new_complexv (GNM_CSCALE (GNM_CLN (c), 1 / M_LN2gnum), imunit);
479 /***************************************************************************/
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}
491 static GnmValue *
492 gnumeric_imlog10 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
494 gnm_complex c;
495 char imunit;
497 if (value_get_as_complex (argv[0], &c, &imunit))
498 return value_new_error_NUM (ei->pos);
500 return value_new_complexv (GNM_CSCALE (GNM_CLN (c), M_LN10INVgnum), imunit);
503 /***************************************************************************/
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}
516 static GnmValue *
517 gnumeric_impower (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
519 gnm_complex a, b;
520 char imunit;
522 if (value_get_as_complex (argv[0], &a, &imunit))
523 return value_new_error_NUM (ei->pos);
525 if (value_get_as_complex (argv[1], &b, &imunit))
526 return value_new_error_NUM (ei->pos);
528 if (GNM_CZEROP (a) && GNM_CZEROP (b))
529 return value_new_error_DIV0 (ei->pos);
531 return value_new_complexv (GNM_CPOW (a, b), imunit);
534 /***************************************************************************/
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}
548 static GnmValue *
549 gnumeric_imdiv (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
551 gnm_complex a, b;
552 char imunit;
554 if (value_get_as_complex (argv[0], &a, &imunit))
555 return value_new_error_NUM (ei->pos);
557 if (value_get_as_complex (argv[1], &b, &imunit))
558 return value_new_error_NUM (ei->pos);
560 if (GNM_CZEROP (b))
561 return value_new_error_DIV0 (ei->pos);
563 return value_new_complexv (GNM_CDIV (a, b), imunit);
566 /***************************************************************************/
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}
578 static GnmValue *
579 gnumeric_imsin (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
581 gnm_complex c;
582 char imunit;
584 if (value_get_as_complex (argv[0], &c, &imunit))
585 return value_new_error_NUM (ei->pos);
587 return value_new_complexv (GNM_CSIN (c), imunit);
590 /***************************************************************************/
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}
601 static GnmValue *
602 gnumeric_imsinh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
604 gnm_complex c;
605 char imunit;
607 if (value_get_as_complex (argv[0], &c, &imunit))
608 return value_new_error_NUM (ei->pos);
610 return value_new_complexv (GNM_CSINH (c), imunit);
613 /***************************************************************************/
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}
625 static GnmValue *
626 gnumeric_imcosh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
628 gnm_complex c;
629 char imunit;
631 if (value_get_as_complex (argv[0], &c, &imunit))
632 return value_new_error_NUM (ei->pos);
634 return value_new_complexv (GNM_CCOSH (c), imunit);
637 /***************************************************************************/
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}
649 static GnmValue *
650 gnumeric_imtanh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
652 gnm_complex c;
653 char imunit;
655 if (value_get_as_complex (argv[0], &c, &imunit))
656 return value_new_error_NUM (ei->pos);
658 return value_new_complexv (GNM_CTANH (c), imunit);
661 /***************************************************************************/
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}
672 static GnmValue *
673 gnumeric_imsech (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
675 gnm_complex c;
676 char imunit;
678 if (value_get_as_complex (argv[0], &c, &imunit))
679 return value_new_error_NUM (ei->pos);
681 return value_new_complexv (GNM_CSECH (c), imunit);
684 /***************************************************************************/
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}
696 static GnmValue *
697 gnumeric_imcsch (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
699 gnm_complex c;
700 char imunit;
702 if (value_get_as_complex (argv[0], &c, &imunit))
703 return value_new_error_NUM (ei->pos);
705 return value_new_complexv (GNM_CCSCH (c), imunit);
708 /***************************************************************************/
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}
719 static GnmValue *
720 gnumeric_imcoth (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
722 gnm_complex c;
723 char imunit;
725 if (value_get_as_complex (argv[0], &c, &imunit))
726 return value_new_error_NUM (ei->pos);
728 return value_new_complexv (GNM_CCOTH (c), imunit);
731 /***************************************************************************/
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}
745 static GnmValue *
746 gnumeric_imarcsin (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
748 gnm_complex c;
749 char imunit;
751 if (value_get_as_complex (argv[0], &c, &imunit))
752 return value_new_error_NUM (ei->pos);
754 return value_new_complexv (GNM_CARCSIN (c), imunit);
757 /***************************************************************************/
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}
771 static GnmValue *
772 gnumeric_imarccos (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
774 gnm_complex c;
775 char imunit;
777 if (value_get_as_complex (argv[0], &c, &imunit))
778 return value_new_error_NUM (ei->pos);
780 return value_new_complexv (GNM_CARCCOS (c), imunit);
783 /***************************************************************************/
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}
797 static GnmValue *
798 gnumeric_imarctan (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
800 gnm_complex c;
801 char imunit;
803 if (value_get_as_complex (argv[0], &c, &imunit))
804 return value_new_error_NUM (ei->pos);
806 return value_new_complexv (GNM_CARCTAN (c), imunit);
809 /***************************************************************************/
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}
820 static GnmValue *
821 gnumeric_imarcsec (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
823 gnm_complex c;
824 char imunit;
826 if (value_get_as_complex (argv[0], &c, &imunit))
827 return value_new_error_NUM (ei->pos);
829 return value_new_complexv (GNM_CARCSEC (c), imunit);
832 /***************************************************************************/
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}
844 static GnmValue *
845 gnumeric_imarccsc (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
847 gnm_complex c;
848 char imunit;
850 if (value_get_as_complex (argv[0], &c, &imunit))
851 return value_new_error_NUM (ei->pos);
853 return value_new_complexv (GNM_CARCCSC (c), imunit);
856 /***************************************************************************/
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}
867 static GnmValue *
868 gnumeric_imarccot (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
870 gnm_complex c;
871 char imunit;
873 if (value_get_as_complex (argv[0], &c, &imunit))
874 return value_new_error_NUM (ei->pos);
876 return value_new_complexv (GNM_CARCCOT (c), imunit);
879 /***************************************************************************/
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}
893 static GnmValue *
894 gnumeric_imarcsinh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
896 gnm_complex c;
897 char imunit;
899 if (value_get_as_complex (argv[0], &c, &imunit))
900 return value_new_error_NUM (ei->pos);
902 return value_new_complexv (GNM_CARCSINH (c), imunit);
905 /***************************************************************************/
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}
920 static GnmValue *
921 gnumeric_imarccosh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
923 gnm_complex c;
924 char imunit;
926 if (value_get_as_complex (argv[0], &c, &imunit))
927 return value_new_error_NUM (ei->pos);
929 return value_new_complexv (GNM_CARCCOSH (c), imunit);
932 /***************************************************************************/
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}
947 static GnmValue *
948 gnumeric_imarctanh (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
950 gnm_complex c;
951 char imunit;
953 if (value_get_as_complex (argv[0], &c, &imunit))
954 return value_new_error_NUM (ei->pos);
956 return value_new_complexv (GNM_CARCTANH (c), imunit);
959 /***************************************************************************/
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}
970 static GnmValue *
971 gnumeric_imarcsech (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
973 gnm_complex c;
974 char imunit;
976 if (value_get_as_complex (argv[0], &c, &imunit))
977 return value_new_error_NUM (ei->pos);
979 return value_new_complexv (GNM_CARCSECH (c), imunit);
982 /***************************************************************************/
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}
994 static GnmValue *
995 gnumeric_imarccsch (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
997 gnm_complex c;
998 char imunit;
1000 if (value_get_as_complex (argv[0], &c, &imunit))
1001 return value_new_error_NUM (ei->pos);
1003 return value_new_complexv (GNM_CARCCSCH (c), imunit);
1006 /***************************************************************************/
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}
1018 static GnmValue *
1019 gnumeric_imarccoth (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1021 gnm_complex c;
1022 char imunit;
1024 if (value_get_as_complex (argv[0], &c, &imunit))
1025 return value_new_error_NUM (ei->pos);
1027 return value_new_complexv (GNM_CARCCOTH (c), imunit);
1030 /***************************************************************************/
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}
1043 static GnmValue *
1044 gnumeric_imsqrt (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1046 gnm_complex c;
1047 char imunit;
1049 if (value_get_as_complex (argv[0], &c, &imunit))
1050 return value_new_error_NUM (ei->pos);
1052 return value_new_complexv (GNM_CSQRT (c), imunit);
1055 /***************************************************************************/
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}
1067 static GnmValue *
1068 gnumeric_imfact (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1070 gnm_complex c;
1071 char imunit;
1073 if (value_get_as_complex (argv[0], &c, &imunit))
1074 return value_new_error_NUM (ei->pos);
1076 return value_new_complexv (gnm_complex_fact (c, NULL), imunit);
1079 /***************************************************************************/
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}
1091 static GnmValue *
1092 gnumeric_imgamma (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1094 gnm_complex c;
1095 char imunit;
1097 if (value_get_as_complex (argv[0], &c, &imunit))
1098 return value_new_error_NUM (ei->pos);
1100 return value_new_complexv (gnm_complex_gamma (c, NULL), imunit);
1103 /***************************************************************************/
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}
1119 static GnmValue *
1120 gnumeric_imigamma (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
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;
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);
1132 return value_new_complexv (gnm_complex_igamma (a, z, lower, reg), imunit);
1135 /***************************************************************************/
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}
1149 static GnmValue *
1150 gnumeric_imsub (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
1152 gnm_complex a, b;
1153 char imunit;
1155 if (value_get_as_complex (argv[0], &a, &imunit))
1156 return value_new_error_NUM (ei->pos);
1158 if (value_get_as_complex (argv[1], &b, &imunit))
1159 return value_new_error_NUM (ei->pos);
1161 return value_new_complexv (GNM_CSUB (a, b), imunit);
1164 /***************************************************************************/
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}
1178 typedef enum {
1179 Improduct, Imsum
1180 } eng_imoper_type_t;
1182 typedef struct {
1183 gnm_complex res;
1184 char imunit;
1185 eng_imoper_type_t type;
1186 } eng_imoper_t;
1188 static GnmValue *
1189 callback_function_imoper (GnmEvalPos const *ep, GnmValue const *value, void *closure)
1191 eng_imoper_t *result = closure;
1192 gnm_complex c;
1193 char *imptr, dummy;
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);
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 ();
1210 return NULL;
1213 static GnmValue *
1214 gnumeric_improduct (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
1216 GnmValue *v;
1217 eng_imoper_t p;
1219 p.type = Improduct;
1220 p.imunit = 'j';
1221 p.res = GNM_C1;
1223 v = function_iterate_argument_values
1224 (ei->pos, callback_function_imoper, &p,
1225 argc, argv, TRUE, CELL_ITER_IGNORE_BLANK);
1227 if (v != NULL)
1228 return v;
1230 return value_new_complexv (p.res, p.imunit);
1233 /***************************************************************************/
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}
1247 static GnmValue *
1248 gnumeric_imsum (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
1250 GnmValue *v;
1251 eng_imoper_t p;
1253 p.type = Imsum;
1254 p.imunit = 'j';
1255 p.res = GNM_C0;
1257 v = function_iterate_argument_values
1258 (ei->pos, callback_function_imoper, &p,
1259 argc, argv, TRUE, CELL_ITER_IGNORE_BLANK);
1261 if (v != NULL)
1262 return v;
1264 return value_new_complexv (p.res, p.imunit);
1267 /***************************************************************************/
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 },
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 },
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 },
1408 {NULL}