9 static int liba_complex_isok(lua_State
*L
, int idx
)
12 if (lua_getmetatable(L
, idx
))
14 lua_registry_get(L
, liba_complex_new
);
15 ok
= lua_rawequal(L
, -1, -2);
21 static int liba_complex_from(lua_State
*L
, a_complex
*z
, int idx
)
23 int type
= lua_type(L
, idx
);
27 z
->real
= (a_float
)lua_tonumber(L
, idx
);
31 a_complex_parse(z
, lua_tostring(L
, idx
));
34 if (liba_complex_isok(L
, idx
))
36 *z
= *(a_complex
*)lua_touserdata(L
, idx
);
47 static a_complex
*liba_complex_new_(lua_State
*L
)
49 a_complex
*const ctx
= lua_newclass(L
, a_complex
);
50 lua_registry_get(L
, liba_complex_new
);
51 lua_setmetatable(L
, -2);
55 static int liba_complex_tostring(lua_State
*L
)
57 a_complex
const *const ctx
= (a_complex
const *)lua_touserdata(L
, 1);
60 lua_pushfstring(L
, "(%f,%f)", (double)ctx
->real
, (double)ctx
->imag
);
67 constructor for complex number from real and imaginary parts
68 @tparam[opt] number|string|a.complex real real part of complex number
69 @tparam[opt] number imag imaginary part of complex number
70 @treturn a.complex complex number userdata
73 int liba_complex_new(lua_State
*L
)
75 a_complex z
= A_COMPLEX_C(0.0, 0.0);
76 int const top
= lua_gettop(L
);
79 int const type
= liba_complex_from(L
, &z
, 1);
80 if (type
== LUA_TNUMBER
&& top
>= 2)
82 z
.imag
= (a_float
)lua_tonumber(L
, 2);
85 *liba_complex_new_(L
) = z
;
90 constructor for complex number from rectangular Cartesian components
91 @tparam[opt] number real real part of complex number
92 @tparam[opt] number imag imaginary part of complex number
93 @treturn a.complex complex number userdata
96 int liba_complex_rect(lua_State
*L
)
98 a_float real
= 0, imag
= 0;
99 int const top
= lua_gettop(L
);
100 if (top
>= 1) { real
= (a_float
)lua_tonumber(L
, 1); }
101 if (top
>= 2) { imag
= (a_float
)lua_tonumber(L
, 2); }
102 a_complex_rect(liba_complex_new_(L
), real
, imag
);
107 constructor for complex number from polar form
108 @tparam[opt] number rho a distance from a reference point
109 @tparam[opt] number theta an angle from a reference direction
110 @treturn a.complex complex number userdata
113 int liba_complex_polar(lua_State
*L
)
115 a_float rho
= 0, theta
= 0;
116 int const top
= lua_gettop(L
);
117 if (top
>= 1) { rho
= (a_float
)lua_tonumber(L
, 1); }
118 if (top
>= 2) { theta
= (a_float
)lua_tonumber(L
, 2); }
119 a_complex_polar(liba_complex_new_(L
), rho
, theta
);
124 complex number x is equal to complex number y
125 @tparam a.complex x complex number on the left
126 @tparam a.complex y complex number on the right
127 @treturn bool result of comparison
130 int liba_complex_eq(lua_State
*L
)
132 if (lua_gettop(L
) >= 2)
135 liba_complex_from(L
, &x
, 1);
136 liba_complex_from(L
, &y
, 2);
137 lua_pushboolean(L
, a_complex_eq(x
, y
));
144 complex number x is not equal to complex number y
145 @tparam a.complex x complex number on the left
146 @tparam a.complex y complex number on the right
147 @treturn bool result of comparison
150 int liba_complex_ne(lua_State
*L
)
152 if (lua_gettop(L
) >= 2)
155 liba_complex_from(L
, &x
, 1);
156 liba_complex_from(L
, &y
, 2);
157 lua_pushboolean(L
, a_complex_ne(x
, y
));
165 int liba_complex_##func(lua_State *L) \
167 if (lua_gettop(L) >= 1) \
170 liba_complex_from(L, &z, 1); \
171 z.real = a_complex_##func(z); \
172 lua_pushnumber(L, (lua_Number)z.real); \
178 computes the natural logarithm of magnitude of a complex number
179 @tparam a.complex z complex number userdata
180 @treturn number log|z|
185 computes the squared magnitude of a complex number
186 @tparam a.complex z complex number userdata
187 @treturn number a^2+b^2
192 computes the magnitude of a complex number
193 @tparam a.complex z complex number userdata
194 @treturn number sqrt{a^2+b^2}
199 computes the phase angle of a complex number
200 @tparam a.complex z complex number userdata
201 @treturn number arctan(b/a)
207 int liba_complex_##func(lua_State *L) \
209 if (lua_gettop(L) >= 1) \
212 ctx = liba_complex_new_(L); \
213 liba_complex_from(L, &z, 1); \
214 a_complex_##func(ctx, z); \
220 computes the projection on Riemann sphere
221 @tparam a.complex z complex number userdata
222 @treturn a.complex complex number userdata
227 computes the complex conjugate
228 @tparam a.complex z complex number userdata
229 @treturn a.complex complex number userdata
234 computes the complex negative
235 @tparam a.complex z complex number userdata
236 @treturn a.complex complex number userdata
241 inverse of a complex number
242 @tparam a.complex z complex number userdata
243 @treturn a.complex complex number userdata
249 int liba_complex_##func(lua_State *L) \
251 if (lua_gettop(L) >= 2) \
253 a_complex x, y, *ctx; \
254 ctx = liba_complex_new_(L); \
255 liba_complex_from(L, &x, 1); \
256 liba_complex_from(L, &y, 2); \
257 a_complex_##func(ctx, x, y); \
264 int liba_complex_##func(lua_State *L) \
266 if (lua_gettop(L) >= 2) \
268 a_complex x, y, *ctx = liba_complex_new_(L); \
269 liba_complex_from(L, &x, 1); \
270 if (liba_complex_from(L, &y, 2) == LUA_TNUMBER) \
272 a_complex_##func##_real(ctx, x, y.real); \
274 else { a_complex_##func(ctx, x, y); } \
280 addition of complex numbers
281 @tparam a.complex x complex number userdata
282 @tparam a.complex y complex number userdata
283 @treturn a.complex complex number userdata
288 subtraction of complex numbers
289 @tparam a.complex x complex number userdata
290 @tparam a.complex y complex number userdata
291 @treturn a.complex complex number userdata
296 multiplication of complex numbers
297 @tparam a.complex x complex number userdata
298 @tparam a.complex y complex number userdata
299 @treturn a.complex complex number userdata
304 division of complex numbers
305 @tparam a.complex x complex number userdata
306 @tparam a.complex y complex number userdata
307 @treturn a.complex complex number userdata
312 complex number z raised to complex power a
313 @tparam a.complex z complex number userdata
314 @tparam a.complex a complex number userdata
315 @treturn a.complex complex number userdata
320 computes the complex base-b logarithm
321 @tparam a.complex z complex number userdata
322 @tparam a.complex b complex number userdata
323 @treturn a.complex complex number userdata
329 int liba_complex_##func(lua_State *L) \
331 if (lua_gettop(L) >= 1) \
334 ctx = liba_complex_new_(L); \
335 liba_complex_from(L, &z, 1); \
336 a_complex_##func(ctx, z); \
343 int liba_complex_##func(lua_State *L) \
345 if (lua_gettop(L) >= 1) \
347 a_complex z, *ctx = liba_complex_new_(L); \
348 int type = liba_complex_from(L, &z, 1); \
349 if (type == LUA_TNUMBER) \
351 a_complex_##func##_real(ctx, z.real); \
353 else { a_complex_##func(ctx, z); } \
359 computes the complex base-e exponential
360 @tparam a.complex z complex number userdata
361 @treturn a.complex complex number userdata
366 computes the complex natural logarithm
367 @tparam a.complex z complex number userdata
368 @treturn a.complex complex number userdata
373 computes the complex square root
374 @tparam a.complex z complex number userdata
375 @treturn a.complex complex number userdata
380 computes the complex base-2 logarithm
381 @tparam a.complex z complex number userdata
382 @treturn a.complex complex number userdata
387 computes the complex base-10 logarithm
388 @tparam a.complex z complex number userdata
389 @treturn a.complex complex number userdata
394 computes the complex sine
395 @tparam a.complex z complex number userdata
396 @treturn a.complex complex number userdata
401 computes the complex cosine
402 @tparam a.complex z complex number userdata
403 @treturn a.complex complex number userdata
408 computes the complex tangent
409 @tparam a.complex z complex number userdata
410 @treturn a.complex complex number userdata
415 computes the complex secant
416 @tparam a.complex z complex number userdata
417 @treturn a.complex complex number userdata
422 computes the complex cosecant
423 @tparam a.complex z complex number userdata
424 @treturn a.complex complex number userdata
429 computes the complex cotangent
430 @tparam a.complex z complex number userdata
431 @treturn a.complex complex number userdata
436 computes the complex arc sine
437 @tparam a.complex z complex number userdata
438 @treturn a.complex complex number userdata
443 computes the complex arc cosine
444 @tparam a.complex z complex number userdata
445 @treturn a.complex complex number userdata
450 computes the complex arc tangent
451 @tparam a.complex z complex number userdata
452 @treturn a.complex complex number userdata
457 computes the complex arc secant
458 @tparam a.complex z complex number userdata
459 @treturn a.complex complex number userdata
464 computes the complex arc cosecant
465 @tparam a.complex z complex number userdata
466 @treturn a.complex complex number userdata
471 computes the complex arc cotangent
472 @tparam a.complex z complex number userdata
473 @treturn a.complex complex number userdata
478 computes the complex hyperbolic sine
479 @tparam a.complex z complex number userdata
480 @treturn a.complex complex number userdata
485 computes the complex hyperbolic cosine
486 @tparam a.complex z complex number userdata
487 @treturn a.complex complex number userdata
492 computes the complex hyperbolic tangent
493 @tparam a.complex z complex number userdata
494 @treturn a.complex complex number userdata
499 computes the complex hyperbolic secant
500 @tparam a.complex z complex number userdata
501 @treturn a.complex complex number userdata
506 computes the complex hyperbolic cosecant
507 @tparam a.complex z complex number userdata
508 @treturn a.complex complex number userdata
513 computes the complex hyperbolic cotangent
514 @tparam a.complex z complex number userdata
515 @treturn a.complex complex number userdata
520 computes the complex arc hyperbolic sine
521 @tparam a.complex z complex number userdata
522 @treturn a.complex complex number userdata
527 computes the complex arc hyperbolic cosine
528 @tparam a.complex z complex number userdata
529 @treturn a.complex complex number userdata
534 computes the complex arc hyperbolic tangent
535 @tparam a.complex z complex number userdata
536 @treturn a.complex complex number userdata
541 computes the complex arc hyperbolic secant
542 @tparam a.complex z complex number userdata
543 @treturn a.complex complex number userdata
548 computes the complex arc hyperbolic cosecant
549 @tparam a.complex z complex number userdata
550 @treturn a.complex complex number userdata
555 computes the complex arc hyperbolic cotangent
556 @tparam a.complex z complex number userdata
557 @treturn a.complex complex number userdata
562 static int liba_complex_set(lua_State
*L
)
564 a_complex
*const ctx
= (a_complex
*)lua_touserdata(L
, 1);
565 switch (a_hash_bkdr(lua_tostring(L
, 2), 0))
567 case 0x0F6133A2: // real
568 ctx
->real
= (a_float
)luaL_checknumber(L
, 3);
570 case 0x0E2E9172: // imag
571 ctx
->imag
= (a_float
)luaL_checknumber(L
, 3);
573 case 0x001E0FA9: // rho
575 a_float
const rho
= (a_float
)luaL_checknumber(L
, 3);
576 a_float
const theta
= a_complex_arg(*ctx
);
577 a_complex_polar(ctx
, rho
, theta
);
580 case 0x0240D1F6: // theta
582 a_float
const theta
= (a_float
)luaL_checknumber(L
, 3);
583 a_float
const rho
= a_complex_abs(*ctx
);
584 a_complex_polar(ctx
, rho
, theta
);
587 case 0x0CD3E0FC: // __eq
588 case 0x906DF07D: // __len
589 case 0x90705068: // __unm
590 case 0x906B0E8D: // __add
591 case 0x906FCDE0: // __sub
592 case 0x906E3BB4: // __mul
593 case 0x906BDA49: // __div
594 case 0x906F01C8: // __pow
595 case 0xE8859EEB: // __name
596 case 0xA65758B2: // __index
597 case 0xAEB551C6: // __newindex
598 case 0x5DA21A54: // __tostring
601 lua_getmetatable(L
, 1);
608 static int liba_complex_get(lua_State
*L
)
610 a_complex
const *const ctx
= (a_complex
const *)lua_touserdata(L
, 1);
611 switch (a_hash_bkdr(lua_tostring(L
, 2), 0))
613 case 0x0F6133A2: // real
614 lua_pushnumber(L
, (lua_Number
)ctx
->real
);
616 case 0x0E2E9172: // imag
617 lua_pushnumber(L
, (lua_Number
)ctx
->imag
);
619 case 0x001E0FA9: // rho
620 lua_pushnumber(L
, (lua_Number
)a_complex_abs(*ctx
));
622 case 0x0240D1F6: // theta
623 lua_pushnumber(L
, (lua_Number
)a_complex_arg(*ctx
));
625 case 0xA65758B2: // __index
626 lua_registry_get(L
, liba_complex_new
);
627 lua_num_set(L
, -1, "real", ctx
->real
);
628 lua_num_set(L
, -1, "imag", ctx
->imag
);
629 lua_num_set(L
, -1, "rho", a_complex_abs(*ctx
));
630 lua_num_set(L
, -1, "theta", a_complex_arg(*ctx
));
633 lua_getmetatable(L
, 1);
640 static int liba_complex_(lua_State
*L
)
642 lua_pushcfunction(L
, liba_complex_new
);
644 lua_call(L
, lua_gettop(L
) - 1, 1);
648 int luaopen_liba_complex(lua_State
*L
)
650 static lua_fun
const funcs
[] = {
651 {"new", liba_complex_new
},
652 {"rect", liba_complex_rect
},
653 {"polar", liba_complex_polar
},
654 {"eq", liba_complex_eq
},
655 {"ne", liba_complex_ne
},
656 {"logabs", liba_complex_logabs
},
657 {"proj", liba_complex_proj
},
658 {"conj", liba_complex_conj
},
659 {"abs2", liba_complex_abs2
},
660 {"abs", liba_complex_abs
},
661 {"arg", liba_complex_arg
},
662 {"unm", liba_complex_neg
},
663 {"add", liba_complex_add
},
664 {"sub", liba_complex_sub
},
665 {"mul", liba_complex_mul
},
666 {"div", liba_complex_div
},
667 {"inv", liba_complex_inv
},
668 {"pow", liba_complex_pow
},
669 {"exp", liba_complex_exp
},
670 {"log", liba_complex_log
},
671 {"log2", liba_complex_log2
},
672 {"log10", liba_complex_log10
},
673 {"logb", liba_complex_logb
},
674 {"sqrt", liba_complex_sqrt
},
675 {"sin", liba_complex_sin
},
676 {"cos", liba_complex_cos
},
677 {"tan", liba_complex_tan
},
678 {"sec", liba_complex_sec
},
679 {"csc", liba_complex_csc
},
680 {"cot", liba_complex_cot
},
681 {"asin", liba_complex_asin
},
682 {"acos", liba_complex_acos
},
683 {"atan", liba_complex_atan
},
684 {"asec", liba_complex_asec
},
685 {"acsc", liba_complex_acsc
},
686 {"acot", liba_complex_acot
},
687 {"sinh", liba_complex_sinh
},
688 {"cosh", liba_complex_cosh
},
689 {"tanh", liba_complex_tanh
},
690 {"sech", liba_complex_sech
},
691 {"csch", liba_complex_csch
},
692 {"coth", liba_complex_coth
},
693 {"asinh", liba_complex_asinh
},
694 {"acosh", liba_complex_acosh
},
695 {"atanh", liba_complex_atanh
},
696 {"asech", liba_complex_asech
},
697 {"acsch", liba_complex_acsch
},
698 {"acoth", liba_complex_acoth
},
700 lua_createtable(L
, 0, A_LEN(funcs
));
701 lua_fun_reg(L
, -1, funcs
, A_LEN(funcs
));
702 lua_createtable(L
, 0, 1);
703 lua_fun_set(L
, -1, "__call", liba_complex_
);
704 lua_setmetatable(L
, -2);
706 static lua_fun
const metas
[] = {
707 {"__tostring", liba_complex_tostring
},
708 {"__newindex", liba_complex_set
},
709 {"__index", liba_complex_get
},
710 {"__len", liba_complex_abs
},
711 {"__unm", liba_complex_neg
},
712 {"__add", liba_complex_add
},
713 {"__sub", liba_complex_sub
},
714 {"__mul", liba_complex_mul
},
715 {"__div", liba_complex_div
},
716 {"__pow", liba_complex_pow
},
717 {"__eq", liba_complex_eq
},
719 lua_createtable(L
, 0, A_LEN(metas
) + A_LEN(funcs
) + 1);
720 lua_fun_reg(L
, -1, metas
, A_LEN(metas
));
721 lua_fun_reg(L
, -1, funcs
, A_LEN(funcs
));
722 lua_str_set(L
, -1, "__name", "a.complex");
723 lua_registry_set(L
, liba_complex_new
);