mag.cpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* Magnitude of complex z
  2. z mag(z)
  3. - ------
  4. a a
  5. -a a
  6. (-1)^a 1
  7. exp(a + i b) exp(a)
  8. a b mag(a) mag(b)
  9. a + i b sqrt(a^2 + b^2)
  10. Notes
  11. 1. Handles mixed polar and rectangular forms, e.g. 1 + exp(i pi/3)
  12. 2. jean-francois.debroux reports that when z=(a+i*b)/(c+i*d) then
  13. mag(numerator(z)) / mag(denominator(z))
  14. must be used to get the correct answer. Now the operation is
  15. automatic.
  16. */
  17. #include "stdafx.h"
  18. #include "defs.h"
  19. void
  20. eval_mag(void)
  21. {
  22. push(cadr(p1));
  23. eval();
  24. mag();
  25. }
  26. void
  27. mag(void)
  28. {
  29. save();
  30. p1 = pop();
  31. push(p1);
  32. numerator();
  33. yymag();
  34. push(p1);
  35. denominator();
  36. yymag();
  37. divide();
  38. restore();
  39. }
  40. void
  41. yymag(void)
  42. {
  43. save();
  44. p1 = pop();
  45. if (isnegativenumber(p1)) {
  46. push(p1);
  47. negate();
  48. } else if (car(p1) == symbol(POWER) && equaln(cadr(p1), -1))
  49. // -1 to a power
  50. push_integer(1);
  51. else if (car(p1) == symbol(POWER) && cadr(p1) == symbol(E)) {
  52. // exponential
  53. push(caddr(p1));
  54. real();
  55. exponential();
  56. } else if (car(p1) == symbol(MULTIPLY)) {
  57. // product
  58. push_integer(1);
  59. p1 = cdr(p1);
  60. while (iscons(p1)) {
  61. push(car(p1));
  62. mag();
  63. multiply();
  64. p1 = cdr(p1);
  65. }
  66. } else if (car(p1) == symbol(ADD)) {
  67. // sum
  68. push(p1);
  69. rect(); // convert polar terms, if any
  70. p1 = pop();
  71. push(p1);
  72. real();
  73. push_integer(2);
  74. power();
  75. push(p1);
  76. imag();
  77. push_integer(2);
  78. power();
  79. add();
  80. push_rational(1, 2);
  81. power();
  82. simplify_trig();
  83. } else
  84. // default (all real)
  85. push(p1);
  86. restore();
  87. }
  88. #if SELFTEST
  89. static char *s[] = {
  90. "mag(a+i*b)",
  91. "(a^2+b^2)^(1/2)",
  92. "mag(exp(a+i*b))",
  93. "exp(a)",
  94. "mag(1)",
  95. "1",
  96. "mag(-1)",
  97. "1",
  98. "mag(1+exp(i*pi/3))",
  99. "3^(1/2)",
  100. "mag((a+i*b)/(c+i*d))",
  101. "(a^2+b^2)^(1/2)/((c^2+d^2)^(1/2))",
  102. "mag(exp(i theta))",
  103. "1",
  104. "mag(exp(-i theta))",
  105. "1",
  106. "mag((-1)^theta)",
  107. "1",
  108. "mag((-1)^(-theta))",
  109. "1",
  110. "mag(3*(-1)^theta)",
  111. "3",
  112. "mag(3*(-1)^(-theta))",
  113. "3",
  114. "mag(-3*(-1)^theta)",
  115. "3",
  116. "mag(-3*(-1)^(-theta))",
  117. "3",
  118. };
  119. void
  120. test_mag(void)
  121. {
  122. test(__FILE__, s, sizeof s / sizeof (char *));
  123. }
  124. #endif