complex.h 5.22 KB
Newer Older
1 2 3
#ifndef GNUMERIC_COMPLEX_H
#define GNUMERIC_COMPLEX_H

Morten Welinder's avatar
Morten Welinder committed
4
#include "numbers.h"
5 6 7
#include <math.h>

typedef struct {
8
	gnm_float re, im;
9 10 11 12 13 14 15 16 17 18 19 20 21
} complex_t;

#ifdef GNUMERIC_COMPLEX_IMPLEMENTATION

/* The actual definitions.  */
#define GNUMERIC_COMPLEX_PROTO(p) p; p
#define GNUMERIC_COMPLEX_BODY

#else

#ifdef __GNUC__

/* Have gcc -- inline functions.  */
22
#define GNUMERIC_COMPLEX_PROTO(p) p; extern __inline__ p
23 24 25 26 27
#define GNUMERIC_COMPLEX_BODY

#else

/* No gcc -- no inline functions.  */
28
#define GNUMERIC_COMPLEX_PROTO(p) extern p;
29 30 31 32 33 34 35 36 37 38 39 40
#undef GNUMERIC_COMPLEX_BODY

#endif
#endif

/* ------------------------------------------------------------------------- */

char *complex_to_string (const complex_t *src, const char *reformat,
			 const char *imformat, char imunit);

int complex_from_string (complex_t *dst, const char *src, char *imunit);

Morten Welinder's avatar
Morten Welinder committed
41 42 43 44 45 46 47
void complex_to_polar (gnm_float *mod, gnm_float *angle, const complex_t *src);
void complex_from_polar (complex_t *dst, gnm_float mod, gnm_float angle);
void complex_mul (complex_t *dst, const complex_t *a, const complex_t *b);
void complex_div (complex_t *dst, const complex_t *a, const complex_t *b);
void complex_sqrt (complex_t *dst, const complex_t *src);
void complex_pow (complex_t *dst, const complex_t *a, const complex_t *b);

48 49
/* ------------------------------------------------------------------------- */

50
GNUMERIC_COMPLEX_PROTO (void complex_init (complex_t *dst, gnm_float re, gnm_float im))
51 52 53 54 55 56 57 58 59
#ifdef GNUMERIC_COMPLEX_BODY
{
	dst->re = re;
	dst->im = im;
}
#endif

/* ------------------------------------------------------------------------- */

60
GNUMERIC_COMPLEX_PROTO (void complex_real (complex_t *dst, gnm_float re))
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
#ifdef GNUMERIC_COMPLEX_BODY
{
	dst->re = re;
	dst->im = 0;
}
#endif

/* ------------------------------------------------------------------------- */

GNUMERIC_COMPLEX_PROTO (int complex_real_p (const complex_t *src))
#ifdef GNUMERIC_COMPLEX_BODY
{
	return src->im == 0;
}
#endif

/* ------------------------------------------------------------------------- */

GNUMERIC_COMPLEX_PROTO (int complex_zero_p (const complex_t *src))
#ifdef GNUMERIC_COMPLEX_BODY
{
	return src->re == 0 && src->im == 0;
}
#endif

/* ------------------------------------------------------------------------- */

88
GNUMERIC_COMPLEX_PROTO (gnm_float complex_mod (const complex_t *src))
89 90
#ifdef GNUMERIC_COMPLEX_BODY
{
91
	return gnm_hypot (src->re, src->im);
92 93 94 95 96
}
#endif

/* ------------------------------------------------------------------------- */

97
GNUMERIC_COMPLEX_PROTO (gnm_float complex_angle (const complex_t *src))
98 99
#ifdef GNUMERIC_COMPLEX_BODY
{
100
	return gnm_atan2 (src->im, src->re);
101 102 103 104 105 106 107 108
}
#endif

/* ------------------------------------------------------------------------- */

GNUMERIC_COMPLEX_PROTO (void complex_conj (complex_t *dst, const complex_t *src))
#ifdef GNUMERIC_COMPLEX_BODY
{
109
	complex_init (dst, src->re, -src->im);
110 111 112 113 114
}
#endif

/* ------------------------------------------------------------------------- */

115
GNUMERIC_COMPLEX_PROTO (void complex_scale_real (complex_t *dst, gnm_float f))
Morten Welinder's avatar
Morten Welinder committed
116 117 118 119 120 121 122 123 124
#ifdef GNUMERIC_COMPLEX_BODY
{
	dst->re *= f;
	dst->im *= f;
}
#endif

/* ------------------------------------------------------------------------- */

125 126 127
GNUMERIC_COMPLEX_PROTO (void complex_add (complex_t *dst, const complex_t *a, const complex_t *b))
#ifdef GNUMERIC_COMPLEX_BODY
{
128
	complex_init (dst, a->re + b->re, a->im + b->im);
129 130 131 132 133 134 135 136
}
#endif

/* ------------------------------------------------------------------------- */

GNUMERIC_COMPLEX_PROTO (void complex_sub (complex_t *dst, const complex_t *a, const complex_t *b))
#ifdef GNUMERIC_COMPLEX_BODY
{
137
	complex_init (dst, a->re - b->re, a->im - b->im);
138 139 140 141 142 143 144 145
}
#endif

/* ------------------------------------------------------------------------- */

GNUMERIC_COMPLEX_PROTO (void complex_exp (complex_t *dst, const complex_t *src))
#ifdef GNUMERIC_COMPLEX_BODY
{
146
	complex_init (dst,
147 148
		      gnm_exp (src->re) * gnm_cos (src->im),
		      gnm_exp (src->re) * gnm_sin (src->im));
149 150 151 152 153 154 155 156
}
#endif

/* ------------------------------------------------------------------------- */

GNUMERIC_COMPLEX_PROTO (void complex_ln (complex_t *dst, const complex_t *src))
#ifdef GNUMERIC_COMPLEX_BODY
{
157
	complex_init (dst,
158
		      gnm_log (complex_mod (src)),
159 160 161 162 163 164
		      complex_angle (src));
}
#endif

/* ------------------------------------------------------------------------- */

165 166 167
GNUMERIC_COMPLEX_PROTO (void complex_sin (complex_t *dst, const complex_t *src))
#ifdef GNUMERIC_COMPLEX_BODY
{
168
	complex_init (dst,
169 170
		      gnm_sin (src->re) * gnm_cosh (src->im),
		      gnm_cos (src->re) * gnm_sinh (src->im));
171 172 173 174 175 176 177 178
}
#endif

/* ------------------------------------------------------------------------- */

GNUMERIC_COMPLEX_PROTO (void complex_cos (complex_t *dst, const complex_t *src))
#ifdef GNUMERIC_COMPLEX_BODY
{
179
	complex_init (dst,
180 181
		      gnm_cos (src->re) * gnm_cosh (src->im),
		      -gnm_sin (src->re) * gnm_sinh (src->im));
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
}
#endif

/* ------------------------------------------------------------------------- */

GNUMERIC_COMPLEX_PROTO (void complex_tan (complex_t *dst, const complex_t *src))
#ifdef GNUMERIC_COMPLEX_BODY
{
	complex_t s, c;

	complex_sin (&s, src);
	complex_cos (&c, src);
	complex_div (dst, &s, &c);
}
#endif

/* ------------------------------------------------------------------------- */

#undef GNUMERIC_COMPLEX_PROTO
#undef GNUMERIC_COMPLEX_BODY

#endif